diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000000..e5b6d8d6a6 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000000..42efc1c834 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.changeset/twelve-deers-search.md b/.changeset/twelve-deers-search.md new file mode 100644 index 0000000000..f87090b079 --- /dev/null +++ b/.changeset/twelve-deers-search.md @@ -0,0 +1,5 @@ +--- +"claude-dev": minor +--- + +Adding changesets for automating version bumping and release notes diff --git a/.changie.yaml b/.changie.yaml new file mode 100644 index 0000000000..bf5f72b64c --- /dev/null +++ b/.changie.yaml @@ -0,0 +1,26 @@ +changesDir: .changes +unreleasedDir: unreleased +headerPath: header.tpl.md +changelogPath: CHANGELOG.md +versionExt: md +versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' +kindFormat: "### {{.Kind}}" +changeFormat: "* {{.Body}}" +kinds: + - label: Added + auto: minor + - label: Changed + auto: major + - label: Deprecated + auto: minor + - label: Removed + auto: major + - label: Fixed + auto: patch + - label: Security + auto: patch +newlines: + afterChangelogHeader: 1 + beforeChangelogVersion: 1 + endOfVersion: 1 +envPrefix: CHANGIE_ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..dd04190cf1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @saoudrizwan @ocasta181 @NightTrek @pashpashpash diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a4dc71c669..989040aab2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,6 +2,10 @@ +### Test Procedure + + + ### Type of Change @@ -17,6 +21,7 @@ - [ ] Changes are limited to a single feature, bugfix or chore (split larger changes into separate PRs) - [ ] Tests are passing (`npm test`) and code is formatted and linted (`npm run format && npm run lint`) +- [ ] I have created a changeset using `npm run changeset` (required for user-facing changes) - [ ] I have reviewed [contributor guidelines](https://github.com/cline/cline/blob/main/CONTRIBUTING.md) ### Screenshots diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py new file mode 100644 index 0000000000..67fdb6a647 --- /dev/null +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -0,0 +1,103 @@ +""" +This script updates a specific version's release notes section in CHANGELOG.md with new content +or reformats existing content. + +The script: +1. Takes a version number, changelog path, and optionally new content as input from environment variables +2. Finds the section in the changelog for the specified version +3. Either: + a) Replaces the content with new content if provided, or + b) Reformats existing content by: + - Removing the first two lines of the changeset format + - Ensuring version numbers are wrapped in square brackets +4. Writes the updated changelog back to the file + +Environment Variables: + CHANGELOG_PATH: Path to the changelog file (defaults to 'CHANGELOG.md') + VERSION: The version number to update/format + PREV_VERSION: The previous version number (used to locate section boundaries) + NEW_CONTENT: Optional new content to insert for this version +""" + +#!/usr/bin/env python3 + +import os +import sys + +CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md") +VERSION = os.environ['VERSION'] +PREV_VERSION = os.environ.get("PREV_VERSION", "") +NEW_CONTENT = os.environ.get("NEW_CONTENT", "") + +def overwrite_changelog_section(changelog_text: str, new_content: str): + # Find the section for the specified version + version_pattern = f"## {VERSION}\n" + bracketed_version_pattern = f"## [{VERSION}]\n" + prev_version_pattern = f"## [{PREV_VERSION}]\n" + print(f"latest version: {VERSION}") + print(f"prev_version: {PREV_VERSION}") + + # Try both unbracketed and bracketed version patterns + version_index = changelog_text.find(version_pattern) + if version_index == -1: + version_index = changelog_text.find(bracketed_version_pattern) + if version_index == -1: + # If version not found, add it at the top (after the first line) + first_newline = changelog_text.find('\n') + if first_newline == -1: + # If no newline found, just prepend + return f"## [{VERSION}]\n\n{changelog_text}" + return f"{changelog_text[:first_newline + 1]}## [{VERSION}]\n\n{changelog_text[first_newline + 1:]}" + else: + # Using bracketed version + version_pattern = bracketed_version_pattern + + notes_start_index = version_index + len(version_pattern) + notes_end_index = changelog_text.find(prev_version_pattern, notes_start_index) if PREV_VERSION and prev_version_pattern in changelog_text else len(changelog_text) + + if new_content: + return changelog_text[:notes_start_index] + f"{new_content}\n" + changelog_text[notes_end_index:] + else: + changeset_lines = changelog_text[notes_start_index:notes_end_index].split("\n") + # Ensure we have at least 2 lines before removing them + if len(changeset_lines) < 2: + print("Warning: Changeset content has fewer than 2 lines") + parsed_lines = "\n".join(changeset_lines) + else: + # Remove the first two lines from the regular changeset format, ex: \n### Patch Changes + parsed_lines = "\n".join(changeset_lines[2:]) + updated_changelog = changelog_text[:notes_start_index] + parsed_lines + changelog_text[notes_end_index:] + # Ensure version number is bracketed + updated_changelog = updated_changelog.replace(f"## {VERSION}", f"## [{VERSION}]") + return updated_changelog + +try: + print(f"Reading changelog from: {CHANGELOG_PATH}") + with open(CHANGELOG_PATH, 'r') as f: + changelog_content = f.read() + + print(f"Changelog content length: {len(changelog_content)} characters") + print("First 200 characters of changelog:") + print(changelog_content[:200]) + print("----------------------------------------------------------------------------------") + + new_changelog = overwrite_changelog_section(changelog_content, NEW_CONTENT) + + print("New changelog content:") + print("----------------------------------------------------------------------------------") + print(new_changelog) + print("----------------------------------------------------------------------------------") + + print(f"Writing updated changelog back to: {CHANGELOG_PATH}") + with open(CHANGELOG_PATH, 'w') as f: + f.write(new_changelog) + + print(f"{CHANGELOG_PATH} updated successfully!") + +except FileNotFoundError: + print(f"Error: Changelog file not found at {CHANGELOG_PATH}") + sys.exit(1) +except Exception as e: + print(f"Error updating changelog: {str(e)}") + print(f"Current working directory: {os.getcwd()}") + sys.exit(1) diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml new file mode 100644 index 0000000000..332b98a66d --- /dev/null +++ b/.github/workflows/changeset-release.yml @@ -0,0 +1,162 @@ +name: Changeset Release +run-name: Changeset Release ${{ github.actor != 'cline-bot' && '- Create PR' || '- Update Changelog' }} + +permissions: + contents: write + pull-requests: write + +on: + workflow_dispatch: + pull_request: + types: [closed, opened, labeled] + +env: + REPO_PATH: ${{ github.repository }} + GIT_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || 'main' }} + +jobs: + # Job 1: Create version bump PR when changesets are merged to main + changeset-pr-version-bump: + if: > + ( github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'main' && + github.actor != 'cline-bot' ) || + github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Git Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + with: + fetch-depth: 0 + ref: ${{ env.GIT_REF }} + + - name: Setup Node.js + uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 + with: + node-version: 20 + cache: "npm" + + - name: Install Dependencies + run: npm run install:all + + # Check if there are any new changesets to process + - name: Check for changesets + id: check-changesets + run: | + NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') + echo "Changesets diff with previous version: $NEW_CHANGESETS" + echo "new_changesets=$NEW_CHANGESETS" >> $GITHUB_OUTPUT + + # Create version bump PR using changesets/action if there are new changesets + - name: Changeset Pull Request + if: steps.check-changesets.outputs.new_changesets != '0' + id: changesets + uses: changesets/action@e9cc34b540dd3ad1b030c57fd97269e8f6ad905a # v1 + with: + commit: "changeset version bump" + title: "Changeset version bump" + version: npm run version-packages # This performs the changeset version bump + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Job 2: Process version bump PR created by cline-bot + changeset-pr-edit-approve: + name: Auto approve and merge Bump version PRs + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + if: > + github.event_name == 'pull_request' && + github.event.pull_request.base.ref == 'main' && + github.actor == 'cline-bot' && + contains(github.event.pull_request.title, 'Changeset version bump') + steps: + - name: Determine checkout ref + id: checkout-ref + run: | + echo "Event action: ${{ github.event.action }}" + echo "Actor: ${{ github.actor }}" + echo "Head ref: ${{ github.head_ref }}" + echo "PR SHA: ${{ github.event.pull_request.head.sha }}" + + if [[ "${{ github.event.action }}" == "opened" && "${{ github.actor }}" == "cline-bot" ]]; then + echo "Using branch ref: ${{ github.head_ref }}" + echo "git_ref=${{ github.head_ref }}" >> $GITHUB_OUTPUT + else + echo "Using SHA ref: ${{ github.event.pull_request.head.sha }}" + echo "git_ref=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT + fi + + - name: Checkout Repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + ref: ${{ steps.checkout-ref.outputs.git_ref }} + + # Get current and previous versions to edit changelog entry + - name: Get version + id: get_version + run: | + VERSION=$(git show HEAD:package.json | jq -r '.version') + echo "version=$VERSION" >> $GITHUB_OUTPUT + PREV_VERSION=$(git show origin/main:package.json | jq -r '.version') + echo "prev_version=$PREV_VERSION" >> $GITHUB_OUTPUT + echo "version=$VERSION" + echo "prev_version=$PREV_VERSION" + + # Update CHANGELOG.md with proper format + - name: Update Changelog Format + if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} + env: + VERSION: ${{ steps.get_version.outputs.version }} + PREV_VERSION: ${{ steps.get_version.outputs.prev_version }} + run: python .github/scripts/overwrite_changeset_changelog.py + + # Commit and push changelog updates + - name: Push Changelog updates + if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} + run: | + git config user.name "cline-bot" + git config user.email github-actions@github.com + echo "Running git add and commit..." + git add CHANGELOG.md + git commit -m "Updating CHANGELOG.md format" + git status + echo "--------------------------------------------------------------------------------" + echo "Pushing to remote..." + echo "--------------------------------------------------------------------------------" + git push + + # Add label to indicate changelog has been formatted + - name: Add changelog-ready label + if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: ['changelog-ready'] + }); + + # Auto-approve PR only after it has been labeled + - name: Auto approve PR + if: contains(github.event.pull_request.labels.*.name, 'changelog-ready') + uses: hmarr/auto-approve-action@de8bf34d0402c38aa2c8346973342b2cb02c4435 # v4 + with: + review-message: "I'm approving since it's a bump version PR" + + # Auto-merge PR + - name: Automerge on PR + if: false # Needs enablePullRequestAutoMerge in repo settings to work contains(github.event.pull_request.labels.*.name, 'changelog-ready') + run: gh pr merge --auto --merge ${{ github.event.pull_request.number }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml new file mode 100644 index 0000000000..48ffc1ca41 --- /dev/null +++ b/.github/workflows/check-changeset.yml @@ -0,0 +1,119 @@ +name: Check Changeset +run-name: Check for Changeset in PR + +permissions: + contents: read + pull-requests: write + +on: + pull_request: + branches: + - main + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + check-changeset: + # Skip draft PRs and dependabot PRs + if: github.event.pull_request.draft == false && github.actor != 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Check for changeset + id: check-changeset + run: | + # Debug info + echo "Current directory: $(pwd)" + echo "PR Base Ref: ${{ github.event.pull_request.base.ref }}" + echo "PR Head Ref: ${{ github.event.pull_request.head.ref }}" + echo "PR Head SHA: ${{ github.event.pull_request.head.sha }}" + echo "Git status:" + git status + + # Get list of changed files + git fetch origin ${{ github.event.pull_request.base.ref }} + CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }} HEAD) + echo "Changed files:" + echo "$CHANGED_FILES" + + echo "Listing .changeset directory:" + ls -la .changeset/ + + # Check if any of the changed files are in docs/ or .github/ + DOCS_ONLY=true + while IFS= read -r file; do + if [[ ! "$file" =~ ^(docs/|.github/) ]]; then + DOCS_ONLY=false + break + fi + done <<< "$CHANGED_FILES" + + # If changes are docs-only, skip changeset check + if [ "$DOCS_ONLY" = true ]; then + echo "Only documentation files were changed, skipping changeset check" + exit 0 + fi + + # Check if any changeset files are in the changed files + CHANGESET_IN_PR=false + while IFS= read -r file; do + if [[ "$file" =~ ^\.changeset/.*\.md$ && "$file" != ".changeset/README.md" ]]; then + echo "Found changeset file in PR: $file" + CHANGESET_IN_PR=true + break + fi + done <<< "$CHANGED_FILES" + + if [ "$CHANGESET_IN_PR" = false ]; then + # Double check local changeset files as backup + CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') + echo "Number of local changesets: $CHANGESETS" + + if [ "$CHANGESETS" -eq 0 ]; then + echo "::error::No changeset file found in PR changes or local directory. Please run 'npm run changeset' to create one." + exit 1 + fi + fi + + - name: Comment on PR + if: failure() + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + with: + script: | + const message = `This PR requires a changeset since it includes user-facing changes. Please: + + 1. Run \`npm run changeset\` locally + 2. Choose the appropriate version bump: + - \`major\` for breaking changes (1.0.0 → 2.0.0) + - \`minor\` for new features (1.0.0 → 1.1.0) + - \`patch\` for bug fixes (1.0.0 → 1.0.1) + 3. Write a clear description of your changes + 4. Commit the generated changeset file + + Note: Documentation-only changes do not require a changeset.`; + + // Get existing comments + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + + // Check if we already commented + const botComment = comments.data.find(comment => + comment.user.login === 'github-actions[bot]' && + comment.body.includes('This PR requires a changeset') + ); + + if (!botComment) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: message + }); + } diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..88388fac7e --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,115 @@ +name: "Publish Release" + +on: + workflow_dispatch: + inputs: + release-type: + description: "Choose release type (release or pre-release)" + required: true + default: "release" + type: choice + options: + - pre-release + - release + +permissions: + contents: write + packages: write + checks: write + pull-requests: write + +jobs: + test: + uses: ./.github/workflows/test.yml + + publish: + needs: test + name: Publish Extension + runs-on: ubuntu-latest + environment: publish + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.15.1 + + # Cache root dependencies - only reuse if package-lock.json exactly matches + - name: Cache root dependencies + uses: actions/cache@v4 + id: root-cache + with: + path: node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + + # Cache webview-ui dependencies - only reuse if package-lock.json exactly matches + - name: Cache webview-ui dependencies + uses: actions/cache@v4 + id: webview-cache + with: + path: webview-ui/node_modules + key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }} + + - name: Install root dependencies + if: steps.root-cache.outputs.cache-hit != 'true' + run: npm ci + + - name: Install webview-ui dependencies + if: steps.webview-cache.outputs.cache-hit != 'true' + run: cd webview-ui && npm ci + + - name: Install Publishing Tools + run: npm install -g vsce ovsx + + - name: Get Version + id: get_version + run: | + VERSION=$(node -p "require('./package.json').version") + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Create Git Tag + id: create_tag + run: | + VERSION=v${{ steps.get_version.outputs.version }} + echo "tag=$VERSION" >> $GITHUB_OUTPUT + echo "Tagging with $VERSION" + git tag "$VERSION" + git push origin "$VERSION" + + - name: Package and Publish Extension + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + run: | + # Required to generate the .vsix + vsce package --out "cline-${{ steps.get_version.outputs.version }}.vsix" + + if [ "${{ github.event.inputs.release-type }}" = "pre-release" ]; then + npm run publish:marketplace:prerelease + echo "Successfully published pre-release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry" + else + npm run publish:marketplace + echo "Successfully published release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry" + fi + + # - name: Get Changelog Entry + # id: changelog + # uses: mindsers/changelog-reader-action@v2 + # with: + # # This expects a standard Keep a Changelog format + # # "latest" means it will read whichever is the most recent version + # # set in "## [1.2.3] - 2025-01-28" style + # version: latest + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ steps.create_tag.outputs.tag }} + files: "*.vsix" + # body: ${{ steps.changelog.outputs.content }} + generate_release_notes: true + prerelease: ${{ github.event.inputs.release-type == 'pre-release' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0587c47dcc..518bc8d244 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,13 @@ on: pull_request: branches: - main + workflow_call: + +# Set default permissions for all jobs +permissions: + contents: read # Needed to check out code + checks: write # Needed to report test results + pull-requests: write # Needed to add comments/annotations to PRs jobs: test: @@ -51,6 +58,5 @@ jobs: - name: Prettier / Format Check run: npm run format - - name: Tests + - name: Extension Tests run: xvfb-run -a npm run test - if: runner.os == 'Linux' diff --git a/.gitignore b/.gitignore index 89382bd731..e6899656c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ out dist node_modules +tmp .vscode-test/ *.vsix .DS_Store + +pnpm-lock.yaml \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000000..f7f6972ae7 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,17 @@ +echo "Running pre-commit checks..." + +# Run ESLint +echo "Running ESLint..." +npm run lint || { + echo "❌ ESLint check failed. Please fix the errors and try committing again." + exit 1 +} + +# Run Prettier +echo "Running Prettier..." +npm run format || { + echo "❌ Prettier check failed. Run 'npm run format:fix' to automatically fix formatting issues." + exit 1 +} + +echo "✅ All checks passed!" diff --git a/.prettierignore b/.prettierignore index 71a9e12197..30f96297f0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,5 @@ dist/ node_modules webview-ui/build/ -CHANGELOG.md -package-lock.json \ No newline at end of file +*.md +package-lock.json diff --git a/.prettierrc.json b/.prettierrc.json index cd4329335c..f2cbe27cf6 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,7 +1,7 @@ { "tabWidth": 4, "useTabs": true, - "printWidth": 120, + "printWidth": 130, "semi": false, "bracketSameLine": true } diff --git a/.vscode-test.mjs b/.vscode-test.mjs index da0108114e..430ee8cadd 100644 --- a/.vscode-test.mjs +++ b/.vscode-test.mjs @@ -1,8 +1,14 @@ import { defineConfig } from "@vscode/test-cli" +import path from "path" export default defineConfig({ - files: "out/**/*.test.js", + files: "{out/**/*.test.js,src/**/*.test.js}", mocha: { + ui: "bdd", timeout: 20000, // Maximum time (in ms) that a test can run before failing }, + workspaceFolder: "test-workspace", + version: "stable", + extensionDevelopmentPath: path.resolve("./"), + launchArgs: ["--disable-extensions"], }) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 5be3c32fb1..a41ce3c1e1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,9 +1,5 @@ { // See http://go.microsoft.com/fwlink/?LinkId=827846 // for the documentation about the extensions.json format - "recommendations": [ - "dbaeumer.vscode-eslint", - "connor4312.esbuild-problem-matchers", - "ms-vscode.extension-test-runner" - ] + "recommendations": ["dbaeumer.vscode-eslint", "connor4312.esbuild-problem-matchers", "ms-vscode.extension-test-runner"] } diff --git a/.vscodeignore b/.vscodeignore index b2518f8b7b..3e7e885a00 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -31,6 +31,9 @@ webview-ui/package-lock.json webview-ui/node_modules/** **/.gitignore +# Ignore docs +docs/** + # Fix issue where codicons don't get packaged (https://github.com/microsoft/vscode-extension-samples/issues/692) !node_modules/@vscode/codicons/dist/codicon.css !node_modules/@vscode/codicons/dist/codicon.ttf diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e1f7dcec..2f6d5e5d65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,106 @@ -# Change Log +# Changelog + +## [3.2.12] + +- Fix command chaining for Windows users +- Fix reasoning_content error for OpenAI providers + +## [3.2.11] + +- Add OpenAI o3-mini model + +## [3.2.10] + +- Improve support for DeepSeek-R1 (deepseek-reasoner) model for OpenRouter, OpenAI-compatible, and DeepSeek direct +- Show Reasoning tokens for models that support it +- Fix issues with switching models between Plan/Act modes + +## [3.2.6] + +- Save last used API/model when switching between Plan and Act, for users that like to use different models for each mode +- New Context Window progress bar in the task header to understand increased cost/generation degradation as the context increases +- Localize READMEs and add language selector for English, Spanish, German, Chinese, and Japanese +- Add Advanced Settings to remove MCP prompts from requests to save tokens, enable/disable checkpoints for users that don't use git (more coming soon!) +- Add Gemini 2.0 Flash Thinking experimental model +- Allow new users to subscribe to mailing list to get notified when new Accounts option is available + +## [3.2.5] + +- Use yellow textfield outline in Plan mode to better distinguish from Act mode + +## [3.2.3] + +- Add DeepSeek-R1 (deepseek-reasoner) model support with proper parameter handling (thanks @slavakurilyak!) + +## [3.2.0] + +- Add Plan/Act mode toggle to let you plan tasks with Cline before letting him get to work +- Easily switch between API providers and models using a new popup menu under the chat field +- Add VS Code LM API provider to run models provided by other VS Code extensions (e.g. GitHub Copilot). Shoutout to @julesmons, @RaySinner, and @MrUbens for putting this together! +- Add on/off toggle for MCP servers to disable them when not in use. Thanks @MrUbens! +- Add Auto-approve option for individual tools in MCP servers. Thanks @MrUbens! + +## [3.1.10] + +- New icon! + +## [3.1.9] + +- Add Mistral API provider with codestral-latest model + +## [3.1.7] + +- Add ability to change viewport size and headless mode when Cline asks to launch the browser + +## [3.1.6] + +- Fix bug where filepaths with Chinese characters would not show up in context mention menu (thanks @chi-chat!) +- Update Anthropic model prices (thanks @timoteostewart!) + +## [3.1.5] + +- Fix bug where Cline couldn't read "@/" import path aliases from tool results + +## [3.1.4] + +- Fix issue where checkpoints would not work for users with git commit signing enabled globally + +## [3.1.2] + +- Fix issue where LFS files would be not be ignored when creating checkpoints + +## [3.1.0] + +- Added checkpoints: Snapshots of workspace are automatically created whenever Cline uses a tool + - Compare changes: Hover over any tool use to see a diff between the snapshot and current workspace state + - Restore options: Choose to restore just the task state, just the workspace files, or both +- New 'See new changes' button appears after task completion, providing an overview of all workspace changes +- Task header now shows disk space usage with a delete button to help manage snapshot storage + +## [3.0.12] + +- Fix DeepSeek API cost reporting (input price is 0 since it's all either a cache read or write, different than how Anthropic reports cache usage) + +## [3.0.11] + +- Emphasize auto-formatting done by the editor in file edit responses for more reliable diff editing + +## [3.0.10] + +- Add DeepSeek provider to API Provider options +- Fix context window limit errors for DeepSeek v3 + +## [3.0.9] + +- Fix bug where DeepSeek v3 would incorrectly escape HTML entities in diff edits + +## [3.0.8] + +- Mitigate DeepSeek v3 diff edit errors by adding 'auto-formatting considerations' to system prompt, encouraging model to use updated file contents as reference point for SEARCH blocks + +## [3.0.7] + +- Revert to using batched file watcher to fix crash when many files would be created at once ## [3.0.6] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 77c38f5e6e..ce24b906bf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,22 @@ Bug reports help make Cline better for everyone! Before creating a new issue, pl Looking for a good first contribution? Check out issues labeled ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) or ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). These are specifically curated for new contributors and areas where we'd love some help! -If you're planning to work on a bigger feature, please create an issue first so we can discuss whether it aligns with Cline's vision. +We also welcome contributions to our [documentation](https://github.com/cline/cline/tree/main/docs)! Whether it's fixing typos, improving existing guides, or creating new educational content - we'd love to build a community-driven repository of resources that helps everyone get the most out of Cline. You can start by diving into `/docs` and looking for areas that need improvement. + +If you're planning to work on a bigger feature, please create a [feature request](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) first so we can discuss whether it aligns with Cline's vision. + +## Development Setup + +1. **VS Code Extensions** + + - When opening the project, VS Code will prompt you to install recommended extensions + - These extensions are required for development - please accept all installation prompts + - If you dismissed the prompts, you can install them manually from the Extensions panel + +2. **Local Development** + - Run `npm run install:all` to install dependencies + - Run `npm run test` to run tests locally + - Before submitting PR, run `npm run format:fix` to format your code ## Writing and Submitting Code @@ -28,8 +43,9 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines 2. **Code Quality** - - Run `npm run lint` to ensure code follows our style guidelines - - Run `npm run format` to format your code with Prettier + - Run `npm run lint` to check code style + - Run `npm run format` to automatically format code + - All PRs must pass CI checks which include both linting and formatting - Address any ESLint warnings or errors before submitting - Follow TypeScript best practices and maintain type safety @@ -40,20 +56,30 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines - Update existing tests if your changes affect them - Include both unit tests and integration tests where appropriate -4. **Commit Guidelines** +4. **Version Management with Changesets** + + - Create a changeset for any user-facing changes using `npm run changeset` + - Choose the appropriate version bump: + - `major` for breaking changes (1.0.0 → 2.0.0) + - `minor` for new features (1.0.0 → 1.1.0) + - `patch` for bug fixes (1.0.0 → 1.0.1) + - Write clear, descriptive changeset messages that explain the impact + - Documentation-only changes don't require changesets + +5. **Commit Guidelines** - Write clear, descriptive commit messages - Use conventional commit format (e.g., "feat:", "fix:", "docs:") - Reference relevant issues in commits using #issue-number -5. **Before Submitting** +6. **Before Submitting** - Rebase your branch on the latest main - Ensure your branch builds successfully - Double-check all tests are passing - Review your changes for any debugging code or console logs -6. **Pull Request Description** +7. **Pull Request Description** - Clearly describe what your changes do - Include steps to test the changes - List any breaking changes diff --git a/LICENSE b/LICENSE index b8f1f99fda..5fb83b31e2 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Cline Bot Inc. + Copyright 2025 Cline Bot Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/README.md b/README.md index 6819183bda..b3e8959beb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# Cline (prev. Claude Dev) – \#1 on OpenRouter +
+English | Español | Deutsch | 日本語 | 简体中文 | 繁體中文 +
+ +# Cline – \#1 on OpenRouter

@@ -11,7 +15,10 @@ Download on VS Marketplace -Join the Discord +Discord + + +r/cline Feature Requests @@ -114,6 +121,22 @@ Thanks to the [Model Context Protocol](https://github.com/modelcontextprotocol), **`@folder`:** Adds folder's files all at once to speed up your workflow even more + + +
+ + + +### Checkpoints: Compare and Restore + +As Cline works through a task, the extension takes a snapshot of your workspace at each step. You can use the 'Compare' button to see a diff between the snapshot and your current workspace, and the 'Restore' button to roll back to that point. + +For example, when working with a local web server, you can use 'Restore Workspace Only' to quickly test different versions of your app, then use 'Restore Task and Workspace' when you find the version you want to continue building from. This lets you safely explore different approaches without losing progress. + + + +
+ ## Contributing To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.md) to learn the basics. You can also join our [Discord](https://discord.gg/cline) to chat with other contributors in the `#contributors` channel. If you're looking for full-time work, check out our open positions on our [careers page](https://cline.bot/join-us)! @@ -137,6 +160,31 @@ To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.m +

+Creating a Pull Request + +1. Before creating a PR, generate a changeset entry: + ```bash + npm run changeset + ``` + This will prompt you for: + - Type of change (major, minor, patch) + - `major` → breaking changes (1.0.0 → 2.0.0) + - `minor` → new features (1.0.0 → 1.1.0) + - `patch` → bug fixes (1.0.0 → 1.0.1) + - Description of your changes + +2. Commit your changes and the generated `.changeset` file + +3. Push your branch and create a PR on GitHub. Our CI will: + - Run tests and checks + - Changesetbot will create a comment showing the version impact + - When merged to main, changesetbot will create a Version Packages PR + - When the Version Packages PR is merged, a new release will be published + +
+ + ## License -[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) +[Apache 2.0 © 2025 Cline Bot Inc.](./LICENSE) diff --git a/assets/icons/icon.png b/assets/icons/icon.png index e8736aaa02..db6f1d8fd1 100644 Binary files a/assets/icons/icon.png and b/assets/icons/icon.png differ diff --git a/assets/icons/icon.svg b/assets/icons/icon.svg new file mode 100644 index 0000000000..2a3908aa4f --- /dev/null +++ b/assets/icons/icon.svg @@ -0,0 +1,16 @@ + + + Group Copy 2 + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/icons/robot_panel_dark.png b/assets/icons/robot_panel_dark.png index 0ed7cc6274..36c37766f9 100644 Binary files a/assets/icons/robot_panel_dark.png and b/assets/icons/robot_panel_dark.png differ diff --git a/assets/icons/robot_panel_light.png b/assets/icons/robot_panel_light.png index bbc7fca4ac..2f028e0a20 100644 Binary files a/assets/icons/robot_panel_light.png and b/assets/icons/robot_panel_light.png differ diff --git a/docs/PRIVACY.md b/docs/PRIVACY.md new file mode 100644 index 0000000000..548948b359 --- /dev/null +++ b/docs/PRIVACY.md @@ -0,0 +1,99 @@ +# Cline Privacy Policy + +Cline Bot Inc. ("Cline," "we," "our," and/or "us") values the privacy of individuals who use our VS Code extension and related services (collectively, our "Services"). This privacy policy explains how we collect, use, and disclose information from users of our Services. + +## Key Points + +- Cline operates entirely client-side as a VS Code extension +- No code or data is collected, stored, or transmitted to Cline's servers +- Your data is only sent to your chosen AI provider (e.g., Anthropic, OpenAI) when you explicitly request assistance +- All processing happens locally on your machine +- API keys are stored securely in VS Code's built-in settings storage + +## Information We Process + +### A. Information You Provide + +- **API Keys**: When you choose to use certain AI model providers (OpenRouter, Anthropic, OpenAI, etc.), you provide API keys. These are stored securely and locally in your VS Code settings. +- **Communications**: If you contact us directly (e.g., via Discord or email), we may receive information like your name, email address, and message contents. + +### B. Information Processing + +Cline functions solely as a client-side VS Code extension that facilitates communication between your editor and your chosen AI model provider: + +1. **File Contents**: + + - Only sent to your chosen AI provider when you explicitly request assistance + - Never stored or transmitted to Cline's servers + - Only the specific files/content you select are included + +2. **Terminal Commands**: + + - Processed entirely locally on your machine + - Require explicit user confirmation before execution + - No command history is transmitted to Cline + +3. **Browser Integration**: + - Screenshots and console logs are processed locally + - Temporary data is cleared after task completion + +## Data Security + +1. **Local-Only Processing**: + + - All operations happen on your local machine + - No central servers or data collection + - No telemetry or usage statistics gathered + - No account creation required + +2. **API Key Security**: + + - Stored using VS Code's secure settings storage system + - Never transmitted to Cline's servers + - You can remove/modify keys at any time + +3. **User Control**: + - Explicit approval required for file changes + - Terminal commands require confirmation + - Browser actions need explicit permission + - You control which AI provider to use + +## Communication with AI Providers + +When you request assistance: + +1. Selected content is sent directly to your chosen AI provider +2. No data passes through Cline's servers +3. Provider's own privacy policy applies to this communication: + - [Anthropic Privacy Policy](https://www.anthropic.com/privacy) + - [OpenAI Privacy Policy](https://openai.com/privacy) + - [OpenRouter Privacy Policy](https://openrouter.ai/privacy) + +## Error Handling & Debugging + +- Error logs are processed locally +- No automatic error reporting to Cline +- You control what information to include when reporting issues + +## Children's Privacy + +We do not knowingly collect, maintain, or use personal information from children under 18 years of age, and no part of our Service(s) is directed to children. If you learn that a child has provided us with personal information in violation of this Privacy Policy, then you may alert us at support@cline.bot. + +## Changes to Privacy Policy + +We will post any changes to this policy on our GitHub repository. Significant changes will be announced in our Discord community. + +## Security Concerns & Auditing + +- Cline is open source and available for security audit +- Our client-side architecture ensures no central point of data collection +- You can inspect exactly what data is being sent to AI providers +- Enterprise users can implement additional access controls through VS Code + +## Contact Us + +For privacy-related questions or concerns: + +- Open an issue on our [GitHub repository](https://github.com/cline/cline) +- Join our [Discord community](https://discord.gg/cline) +- Email: support@cline.bot diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..c2220d6d4d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,38 @@ +# Cline Documentation + +Welcome to the Cline documentation - your comprehensive guide to using and extending Cline's capabilities. Here you'll find resources to help you get started, improve your skills, and contribute to the project. + +## Getting Started + +- **New to coding?** We've prepared a gentle introduction: + - [Getting Started for New Coders](getting-started-new-coders/README.md) + +## Improving Your Prompting Skills + +- **Want to communicate more effectively with Cline?** Explore: + - [Prompt Engineering Guide](prompting/README.md) + - [Cline Memory Bank](prompting/custom%20instructions%20library/cline-memory-bank.md) + +## Exploring Cline's Tools + +- **Understand Cline's capabilities:** + + - [Cline Tools Guide](tools/cline-tools-guide.md) + +- **Extend Cline with MCP Servers:** + - [MCP Overview](mcp/README.md) + - [Building MCP Servers from GitHub](mcp/mcp-server-from-github.md) + - [Building Custom MCP Servers](mcp/mcp-server-from-scratch.md) + +## Contributing to Cline + +- **Interested in contributing?** We welcome your input: + - Feel free to submit a pull request + - [Contribution Guidelines](CONTRIBUTING.md) + +## Additional Resources + +- **Cline GitHub Repository:** [https://github.com/cline/cline](https://github.com/cline/cline) +- **MCP Documentation:** [https://modelcontextprotocol.org/docs](https://modelcontextprotocol.org/docs) + +We're always looking to improve this documentation. If you have suggestions or find areas that could be enhanced, please let us know. Your feedback helps make Cline better for everyone. diff --git a/docs/getting-started-new-coders/README.md b/docs/getting-started-new-coders/README.md new file mode 100644 index 0000000000..40d575197c --- /dev/null +++ b/docs/getting-started-new-coders/README.md @@ -0,0 +1,92 @@ +# Getting Started with Cline | New Coders + +Welcome to Cline! This guide will help you get set up and start using Cline to build your first project. + +## What You'll Need + +Before you begin, make sure you have the following: + +- **VS Code:** A free, powerful code editor. + - [Download VS Code](https://code.visualstudio.com/) +- **Development Tools:** Essential software for coding (Homebrew, Node.js, Git, etc.). + - Follow our [Installing Essential Development Tools](installing-dev-essentials.md) guide to set these up with Cline's help (after getting setup here) + - Cline will guide you through installing everything you need +- **Cline Projects Folder:** A dedicated folder for all your Cline projects. + - On macOS: Create a folder named "Cline" in your Documents folder + - Path: `/Users/[your-username]/Documents/Cline` + - On Windows: Create a folder named "Cline" in your Documents folder + - Path: `C:\Users\[your-username]\Documents\Cline` + - Inside this Cline folder, create separate folders for each project + - Example: `Documents/Cline/workout-app` for a workout tracking app + - Example: `Documents/Cline/portfolio-website` for your portfolio +- **Cline Extension in VS Code:** The Cline extension installed in VS Code. + +- Here's a [tutorial](https://www.youtube.com/watch?v=N4td-fKhsOQ) on everything you need to get started. + +## Step-by-Step Setup + +Follow these steps to get Cline up and running: + +1. **Open VS Code:** Launch the VS Code application. If VS Code shows "Running extensions might...", click "Allow". + +2. **Open Your Cline Folder:** In VS Code, open the Cline folder you created in Documents. + +3. **Navigate to Extensions:** Click on the Extensions icon in the Activity Bar on the side of VS Code. + +4. **Search for 'Cline':** In the Extensions search bar, type "Cline". + +5. **Install the Extension:** Click the "Install" button next to the Cline extension. + +6. **Open Cline:** Once installed, you can open Cline in a few ways: + - Click the Cline icon in the Activity Bar. + - Use the command palette (`CMD/CTRL + Shift + P`) and type "Cline: Open In New Tab" to open Cline as a tab in your editor. This is recommended for a better view. + - **Troubleshooting:** If you don't see the Cline icon, try restarting VS Code. + - **What You'll See:** You should see the Cline chat window appear in your VS Code editor. + +![gettingStartedVsCodeCline](https://github.com/user-attachments/assets/622b4bb7-859b-4c2e-b87b-c12e3eabefb8) + +## Setting up OpenRouter API Key + +Now that you have Cline installed, you'll need to set up your OpenRouter API key to use Cline's full capabilities. + +1. **Get your OpenRouter API Key:** + - [Get your OpenRouter API Key](https://openrouter.ai/) +2. **Input Your OpenRouter API Key:** + - Navigate to the settings button in the Cline extension. + - Input your OpenRouter API key. + - Select your preferred API model. + - **Recommended Models for Coding:** + - `anthropic/claude-3.5-sonnet`: Most used for coding tasks. + - `google/gemini-2.0-flash-exp:free`: A free option for coding. + - `deepseek/deepseek-chat`: SUPER CHEAP, almost as good as 3.5 sonnet + - [OpenRouter Model Rankings](https://openrouter.ai/rankings/programming) + +## Your First Interaction with Cline + +Now you're ready to start building with Cline. Let's create your first project folder and build something! Copy and paste the following prompt into the Cline chat window: + +``` +Hey Cline! Could you help me create a new project folder called "hello-world" in my Cline directory and make a simple webpage that says "Hello World" in big blue text? +``` + +**What You'll See:** Cline will help you create the project folder and set up your first webpage. + +## Tips for Working with Cline + +- **Ask Questions:** If you're unsure about something, don't hesitate to ask Cline! +- **Use Screenshots:** Cline can understand images, so feel free to use screenshots to show him what you're working on. +- **Copy and Paste Errors:** If you encounter errors, copy and paste the error messages into Cline's chat. This will help him understand the issue and provide a solution. +- **Speak Plainly:** Cline is designed to understand plain, non-technical language. Feel free to describe your ideas in your own words, and Cline will translate them into code. + +## FAQs + +- **What is the Terminal?** The terminal is a text-based interface for interacting with your computer. It allows you to run commands to perform various tasks, such as installing packages, running scripts, and managing files. Cline uses the terminal to execute commands and interact with your development environment. +- **How Does the Codebase Work?** (This section will be expanded based on common questions from new coders) + +## Still Struggling? + +Feel free to contact me, and I'll help you get started with Cline. + +nick | 608-558-2410 + +Join our Discord community: [https://discord.gg/cline](https://discord.gg/cline) diff --git a/docs/getting-started-new-coders/installing-dev-essentials.md b/docs/getting-started-new-coders/installing-dev-essentials.md new file mode 100644 index 0000000000..68e1b10f5b --- /dev/null +++ b/docs/getting-started-new-coders/installing-dev-essentials.md @@ -0,0 +1,105 @@ +# Installing Essential Development Tools with Cline | New Coders + +When you start coding, you'll need some essential development tools installed on your computer. Cline can help you install everything you need in a safe, guided way. + +## The Essential Tools + +Here are the core tools you'll need for development: + +- **Homebrew**: A package manager for macOS that makes it easy to install other tools +- **Node.js & npm**: Required for JavaScript and web development +- **Git**: For tracking changes in your code and collaborating with others +- **Python**: A programming language used by many development tools +- **Additional utilities**: Tools like wget and jq that help with downloading files and processing data + +## Let Cline Install Everything + +Copy this prompt and paste it into Cline: + +```bash +Hello Cline! I need help setting up my Mac for software development. Could you please help me install the essential development tools like Homebrew, Node.js, Git, Python, and any other utilities that are commonly needed for coding? I'd like you to guide me through the process step-by-step, explaining what each tool does and making sure everything is installed correctly. +``` + +## What Will Happen + +1. Cline will first install Homebrew, which is like an "app store" for development tools +2. Using Homebrew, Cline will then install other essential tools like Node.js and Git +3. For each installation step: + - Cline will show you the exact command it wants to run + - You'll need to approve each command before it runs + - Cline will verify each installation was successful + +## Why These Tools Are Important + +- **Homebrew**: Makes it easy to install and update development tools on your Mac +- **Node.js & npm**: Required for: + - Building websites with React or Next.js + - Running JavaScript code + - Installing JavaScript packages +- **Git**: Helps you: + - Save different versions of your code + - Collaborate with other developers + - Back up your work +- **Python**: Used for: + - Running development scripts + - Data processing + - Machine learning projects + +## Notes + +- The installation process is interactive - Cline will guide you through each step +- You may need to enter your computer's password for some installations. When prompted, you will not see any characters being typed on the screen. This is normal and is a security feature to protect your password. Just type your password and press Enter. + +**Example:** + +```bash +$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +Password: +``` + +_Type your password here, even though nothing will show up on the screen. Press Enter when you're done._ + +- All commands will be shown to you for approval before they run +- If you run into any issues, Cline will help troubleshoot them + +## Additional Tips for New Coders + +### Understanding the Terminal + +The **Terminal** is an application where you can type commands to interact with your computer. On macOS, you can open it by searching for "Terminal" in Spotlight. + +**Example:** + +```bash +$ open -a Terminal +``` + +### Understanding VS Code Features + +#### Terminal in VS Code + +The **Terminal** in VS Code allows you to run commands directly from within the editor. You can open it by going to `View > Terminal` or by pressing `` Ctrl + ` ``. + +**Example:** + +```bash +$ node -v +v16.14.0 +``` + +#### Document View + +The **Document View** is where you edit your code files. You can open files by clicking on them in the **Explorer** panel on the left side of the screen. + +#### Problems Section + +The **Problems** section in VS Code shows any errors or warnings in your code. You can access it by clicking on the lightbulb icon or by going to `View > Problems`. + +### Common Features + +- **Command Line Interface (CLI)**: This is a text-based interface where you type commands to interact with your computer. It might seem intimidating at first, but it's a powerful tool for developers. +- **Permissions**: Sometimes, you will need to give permissions to certain applications or commands. This is a security measure to ensure that only trusted applications can make changes to your system. + +## Next Steps + +After installing these tools, you'll be ready to start coding! Return to the [Getting Started with Cline for New Coders](../getting-started-new-coders/README.md) guide to continue your journey. diff --git a/docs/mcp/README.md b/docs/mcp/README.md new file mode 100644 index 0000000000..fa5a9bbe22 --- /dev/null +++ b/docs/mcp/README.md @@ -0,0 +1,103 @@ +# Cline and Model Context Protocol (MCP) Servers: Enhancing AI Capabilities + +**Quick Links:** + +- [Building MCP Servers from GitHub](mcp-server-from-github.md) +- [Building Custom MCP Servers from Scratch](mcp-server-from-scratch.md) + +This document explains Model Context Protocol (MCP) servers, their capabilities, and how Cline can help build and use them. + +## Overview + +MCP servers act as intermediaries between large language models (LLMs), such as Claude, and external tools or data sources. They are small programs that expose functionalities to LLMs, enabling them to interact with the outside world through the MCP. An MCP server is essentially like an API that an LLM can use. + +## Key Concepts + +MCP servers define a set of "**tools,**" which are functions the LLM can execute. These tools offer a wide range of capabilities. + +**Here's how MCP works:** + +- **MCP hosts** discover the capabilities of connected servers and load their tools, prompts, and resources. +- **Resources** provide consistent access to read-only data, akin to file paths or database queries. +- **Security** is ensured as servers isolate credentials and sensitive data. Interactions require explicit user approval. + +## Use Cases + +The potential of MCP servers is vast. They can be used for a variety of purposes. + +**Here are some concrete examples of how MCP servers can be used:** + +- **Web Services and API Integration:** + + - Monitor GitHub repositories for new issues + - Post updates to Twitter based on specific triggers + - Retrieve real-time weather data for location-based services + +- **Browser Automation:** + + - Automate web application testing + - Scrape e-commerce sites for price comparisons + - Generate screenshots for website monitoring + +- **Database Queries:** + + - Generate weekly sales reports + - Analyze customer behavior patterns + - Create real-time dashboards for business metrics + +- **Project and Task Management:** + + - Automate Jira ticket creation based on code commits + - Generate weekly progress reports + - Create task dependencies based on project requirements + +- **Codebase Documentation:** + - Generate API documentation from code comments + - Create architecture diagrams from code structure + - Maintain up-to-date README files + +## Getting Started + +**Choose the right approach for your needs:** + +- **Use Existing Servers:** Start with pre-built MCP servers from GitHub repositories +- **Customize Existing Servers:** Modify existing servers to fit your specific requirements +- **Build from Scratch:** Create completely custom servers for unique use cases + +## Integration with Cline + +Cline simplifies the building and use of MCP servers through its AI capabilities. + +### Building MCP Servers + +- **Natural language understanding:** Instruct Cline in natural language to build an MCP server by describing its functionalities. Cline will interpret your instructions and generate the necessary code. +- **Cloning and building servers:** Cline can clone existing MCP server repositories from GitHub and build them automatically. +- **Configuration and dependency management:** Cline handles configuration files, environment variables, and dependencies. +- **Troubleshooting and debugging:** Cline helps identify and resolve errors during development. + +### Using MCP Servers + +- **Tool execution:** Cline seamlessly integrates with MCP servers, allowing you to execute their defined tools. +- **Context-aware interactions:** Cline can intelligently suggest using relevant tools based on conversation context. +- **Dynamic integrations:** Combine multiple MCP server capabilities for complex tasks. For example, Cline could use a GitHub server to get data and a Notion server to create a formatted report. + +## Security Considerations + +When working with MCP servers, it's important to follow security best practices: + +- **Authentication:** Always use secure authentication methods for API access +- **Environment Variables:** Store sensitive information in environment variables +- **Access Control:** Limit server access to authorized users only +- **Data Validation:** Validate all inputs to prevent injection attacks +- **Logging:** Implement secure logging practices without exposing sensitive data + +## Resources + +There are various resources available for finding and learning about MCP servers. + +**Here are some links to resources for finding and learning about MCP servers:** + +- **GitHub Repositories:** [https://github.com/modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) and [https://github.com/punkpeye/awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers) +- **Online Directories:** [https://mcpservers.org/](https://mcpservers.org/), [https://mcp.so/](https://mcp.so/), and [https://glama.ai/mcp/servers](https://glama.ai/mcp/servers) +- **PulseMCP:** [https://www.pulsemcp.com/](https://www.pulsemcp.com/) +- **YouTube Tutorial (AI-Driven Coder):** A video guide for building and using MCP servers: [https://www.youtube.com/watch?v=b5pqTNiuuJg](https://www.youtube.com/watch?v=b5pqTNiuuJg) diff --git a/docs/mcp/mcp-quickstart.md b/docs/mcp/mcp-quickstart.md new file mode 100644 index 0000000000..b1b5700694 --- /dev/null +++ b/docs/mcp/mcp-quickstart.md @@ -0,0 +1,151 @@ +# 🚀 MCP Quickstart Guide + +## ❓ What's an MCP Server? + +Think of MCP servers as special helpers that give Cline extra powers! They let Cline do cool things like fetch web pages or work with your files. + +## ⚠️ IMPORTANT: System Requirements + +STOP! Before proceeding, you MUST verify these requirements: + +### Required Software + +- ✅ Latest Node.js (v18 or newer) + + - Check by running: `node --version` + - Install from: + +- ✅ Latest Python (v3.8 or newer) + + - Check by running: `python --version` + - Install from: + +- ✅ UV Package Manager + - After installing Python, run: `pip install uv` + - Verify with: `uv --version` + +❗ If any of these commands fail or show older versions, please install/update before continuing! + +⚠️ If you run into other errors, see the "Troubleshooting" section below. + +## 🎯 Quick Steps (Only After Requirements Are Met!) + +### 1. 🛠️ Install Your First MCP Server + +1. From the Cline extension, click the `MCP Server` tab +1. Click the `Edit MCP Settings` button + + MCP Server Panel + +1. The MCP settings files should be display in a tab in VS Code. +1. Replace the file's contents with this code: + +For Windows: + +```json +{ + "mcpServers": { + "mcp-installer": { + "command": "cmd.exe", + "args": ["/c", "npx", "-y", "@anaisbetts/mcp-installer"] + } + } +} +``` + +For Mac and Linux: + +```json +{ + "mcpServers": { + "mcp-installer": { + "command": "npx", + "args": ["@anaisbetts/mcp-installer"] + } + } +} +``` + +After saving the file: + +1. Cline will detect the change automatically +2. The MCP installer will be downloaded and installed +3. Cline will start the MCP installer +4. You'll see the server status in Cline's MCP settings UI: + +MCP Server Panel with Installer + +## 🤔 What Next? + +Now that you have the MCP installer, you can ask Cline to add more servers from: + +1. NPM Registry: +2. Python Package Index: + +For example, you can ask Cline to install the `mcp-server-fetch` package found on the Python Package Index: + +```bash +"install the MCP server named `mcp-server-fetch` +- ensure the mcp settings are updated. +- use uvx or python to run the server." +``` + +You should witness Cline: + +1. Install the `mcp-server-fetch` python package +1. Update the mcp setting json file +1. Start the server and start the server + +The mcp settings file should now look like this: + +_For a Windows machine:_ + +```json +{ + "mcpServers": { + "mcp-installer": { + "command": "cmd.exe", + "args": ["/c", "npx", "-y", "@anaisbetts/mcp-installer"] + }, + "mcp-server-fetch": { + "command": "uvx", + "args": ["mcp-server-fetch"] + } + } +} +``` + +You you can always check the status of your server by going to clients MCP server tab. See the image above + +That's it! 🎉 You've just given Cline some awesome new abilities! + +## 📝 Troubleshooting + +### 1. I'm Using `asdf` and Get "unknown command: npx" + +There is some slightly bad news. You should still be able to get things to work, but will have to do a bit more manual work unless MCP server packaging evolves a bit. One option is to uninstall `asdf` , but we will assume you do not want to do that. + +Instead, you will need to follow the instructions above to "Edit MCP Settings". Then, as [this post](https://dev.to/cojiroooo/mcp-using-node-on-asdf-382n) describes, you need to add and "env" entry to each server's configs. + +```json +"env": { + "PATH": "/Users//.asdf/shims:/usr/bin:/bin", + "ASDF_DIR": "", + "ASDF_DATA_DIR": "/Users//.asdf", + "ASDF_NODEJS_VERSION": "" + } +``` + +The `path_to_asdf_bin_dir` can often be found in your shell config (e.g. `.zshrc`). If you are using Homebrew, you can use `echo ${HOMEBREW_PREFIX}` to find the start of the directory and then append `/opt/asdf/libexec`. + +Now for some good news. While not perfect, you can get Cline to do this for you fairly reliably for subsequent server install. Add the following to your "Custom Instructions" in the Cline settings (top-right toolbar button): + +> When installing MCP servers and editing the cline_mcp_settings.json, if the server requires use of `npx` as the command, you must copy the "env" entry from the "mcp-installer" entry and add it to the new entry. This is vital to getting the server to work properly when in use. + +### 2. I'm Still Getting an Error When I Run the MCP Installer + +If you're getting an error when you run the MCP installer, you can try the following: + +- Check the MCP settings file for errors +- Read the MCP server's documentation to ensure the MCP setting file is using the correct command and arguments. 👈 +- Use a terminal and run the command with its arguments directly. This will allow you to see the same errors that Cline is seeing. diff --git a/docs/mcp/mcp-server-from-github.md b/docs/mcp/mcp-server-from-github.md new file mode 100644 index 0000000000..a96f84136c --- /dev/null +++ b/docs/mcp/mcp-server-from-github.md @@ -0,0 +1,67 @@ +# Building MCP Servers from GitHub Repositories + +This guide provides a step-by-step walkthrough of how to use Cline to build an existing MCP server from a GitHub repository. + +## **Finding an MCP Server** + +There are multiple places online to find MCP servers: + +- **Cline can automatically add MCP servers to its list, which you can then edit.** Cline can clone repositories directly from GitHub and build the servers for you. +- **GitHub:** Two of the most common places to find MCP servers on GitHub include: + - [Official MCP servers repository](https://github.com/modelcontextprotocol/servers) + - [Awesome-MCP servers repository](https://github.com/punkpeye/awesome-mcp-servers) +- **Online directories:** Several websites list MCP servers including: + + - [mcpservers.org](https://mcpservers.org/) + - [mcp.so](https://mcp.so/) + - [glama.ai/mcp/servers](https://glama.ai/mcp/servers) + + These directories allow users to sort the servers by various criteria such as downloads, date, stars, and use case. Each entry provides information such as features, tools, and configuration instructions. + +- **PulseMCP:** This website has a blog post discussing how AI could use MCP servers to make websites obsolete. PulseMCP also includes an FAQ section about MCP servers: [https://www.pulsemcp.com/](https://www.pulsemcp.com/) + +## **Building with Cline** + +1. **Initiate the Process:** Provide Cline with the following information: + - **GitHub Repository URL:** The URL of the server's repository. + - **README.md Contents:** This is optional but helpful for Cline to understand the server's purpose and configuration. You can copy the README.md file from the GitHub repository. +2. **Example Interaction with Cline:** + + ``` + User: "Cline, I want to add the MCP server for Brave browser control. Here's the GitHub link: https://github.com/modelcontextprotocol/servers/tree/main/src/brave Can you add it?" + + Cline: "OK. Cloning the repository to the MCP directory. It needs to be built because it has a 'package.json' file. Should I run 'npm run build'?" + + User: "Yes, build it." + + Cline: "Build complete. This server needs a browser path. Where's your Brave browser executable?" + + User: "It's in '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'." + + Cline: "OK. I've updated the server config with that path and added it to 'cline_mcp_settings.json'. Anything else?" + + User: "No, that's all. Let's test it." + + Cline: "Great! Starting the MCP Inspector to test the server connection. After that, we can try controlling the browser from Cline." + ``` + +3. **Cline's Actions:** Based on your instructions, Cline will perform the following: + - **Repository Cloning:** Cline will clone the repository to your local machine, usually in the directory specified in your configuration. + - **Tweaking:** You can guide Cline to modify the server’s configuration. For instance: + - **User:** "This server requires an API key. Can you find where it should be added?" + - Cline may automatically update the `cline_mcp_settings.json` file or other relevant files based on your instructions. + - **Building the Server:** Cline will run the appropriate build command for the server, which is commonly `npm run build`. + - **Adding Server to Settings:** Cline will add the server’s configuration to the `cline_mcp_settings.json` file. + +## **Testing and Troubleshooting** + +1. **Test the Server:** Once Cline finishes the build process, test the server to make sure it works as expected. Cline can assist you if you encounter any problems. +2. **MCP Inspector:** You can use the MCP Inspector to test the server’s connection and functionality. + +## **Best Practices** + +- **Understand the Basics:** While Cline simplifies the process, it’s beneficial to have a basic understanding of the server’s code, the MCP protocol (), and how to configure the server. This allows for more effective troubleshooting and customization. +- **Clear Instructions:** Provide clear and specific instructions to Cline throughout the process. +- **Testing:** Thoroughly test the server after installation and configuration to ensure it functions correctly. +- **Version Control:** Use a version control system (like Git) to track changes to the server’s code. +- **Stay Updated:** Keep your MCP servers updated to benefit from the latest features and security patches. diff --git a/docs/mcp/mcp-server-from-scratch.md b/docs/mcp/mcp-server-from-scratch.md new file mode 100644 index 0000000000..bb3b8934a8 --- /dev/null +++ b/docs/mcp/mcp-server-from-scratch.md @@ -0,0 +1,74 @@ +# Building Custom MCP Servers From Scratch Using Cline: A Comprehensive Guide + +This guide provides a comprehensive walkthrough of building a custom MCP (Model Context Protocol) server from scratch, leveraging the powerful AI capabilities of Cline. The example used will be building a "GitHub Assistant Server" to illustrate the process. + +## Understanding MCP and Cline's Role in Building Servers + +### What is MCP? + +The Model Context Protocol (MCP) acts as a bridge between large language models (LLMs) like Claude and external tools and data. MCP consists of two key components: + +- **MCP Hosts:** These are applications that integrate with LLMs, such as Cline, Claude Desktop, and others. +- **MCP Servers:** These are small programs specifically designed to expose data or specific functionalities to the LLMs through the MCP. + +This setup is beneficial when you have an MCP-compliant chat interface, like Claude Desktop, which can then leverage these servers to access information and execute actions. + +### Why Use Cline to Create MCP Servers? + +Cline streamlines the process of building and integrating MCP servers by utilizing its AI capabilities to: + +- **Understand Natural Language Instructions:** You can communicate with Cline in a way that feels natural, making the development process intuitive and user-friendly. +- **Clone Repositories:** Cline can directly clone existing MCP server repositories from GitHub, simplifying the process of using pre-built servers. +- **Build Servers:** Once the necessary code is in place, Cline can execute commands like `npm run build` to compile and prepare the server for use. +- **Handle Configuration:** Cline manages the configuration files required for the MCP server, including adding the new server to the `cline_mcp_settings.json` file. +- **Assist with Troubleshooting:** If errors arise during development or testing, Cline can help identify the cause and suggest solutions, making debugging easier. + +## Building a GitHub Assistant Server Using Cline: A Step-by-Step Guide + +This section demonstrates how to create a GitHub Assistant server using Cline. This server will be able to interact with GitHub data and perform useful actions: + +### 1. Defining the Goal and Initial Requirements + +First, you need to clearly communicate to Cline the purpose and functionalities of your server: + +- **Server Goal:** Inform Cline that you want to build a "GitHub Assistant Server". Specify that this server will interact with GitHub data and potentially mention the types of data you are interested in, like issues, pull requests, and user profiles. +- **Access Requirements:** Let Cline know that you need to access the GitHub API. Explain that this will likely require a personal access token (GITHUB_TOKEN) for authentication. +- **Data Specificity (Optional):** You can optionally tell Cline about specific fields of data you want to extract from GitHub, but this can also be determined later as you define the server's tools. + +### 2. Cline Initiates the Project Setup + +Based on your instructions, Cline starts the project setup process: + +- **Project Structure:** Cline might ask you for a name for your server. Afterward, it uses the MCP `create-server` tool to generate the basic project structure for your GitHub Assistant server. This usually involves creating a new directory with essential files like `package.json`, `tsconfig.json`, and a `src` folder for your TypeScript code. \ +- **Code Generation:** Cline generates starter code for your server, including: + - **File Handling Utilities:** Functions to help with reading and writing files, commonly used for storing data or logs. \ + - **GitHub API Client:** Code to interact with the GitHub API, often using libraries like `@octokit/graphql`. Cline will likely ask for your GitHub username or the repositories you want to work with. \ + - **Core Server Logic:** The basic framework for handling requests from Cline and routing them to the appropriate functions, as defined by the MCP. \ +- **Dependency Management:** Cline analyzes the code and identifies necessary dependencies, adding them to the `package.json` file. For example, interacting with the GitHub API will likely require packages like `@octokit/graphql`, `graphql`, `axios`, or similar. \ +- **Dependency Installation:** Cline executes `npm install` to download and install the dependencies listed in `package.json`, ensuring your server has all the required libraries to function correctly. \ +- **Path Corrections:** During development, you might move files or directories around. Cline intelligently recognizes these changes and automatically updates file paths in your code to maintain consistency. +- **Configuration:** Cline will modify the `cline_mcp_settings.json` file to add your new GitHub Assistant server. This will include: + - **Server Start Command:** Cline will add the appropriate command to start your server (e.g., `npm run start` or a similar command). + - **Environment Variables:** Cline will add the required `GITHUB_TOKEN` variable. Cline might ask you for your GitHub personal access token, or it might guide you to safely store it in a separate environment file. \ +- **Progress Documentation:** Throughout the process, Cline keeps the "Memory Bank" files updated. These files document the project's progress, highlighting completed tasks, tasks in progress, and pending tasks. + +### 3. Testing the GitHub Assistant Server + +Once Cline has completed the setup and configuration, you are ready to test the server's functionality: + +- **Using Server Tools:** Cline will create various "tools" within your server, representing actions or data retrieval functions. To test, you would instruct Cline to use a specific tool. Here are examples related to GitHub: + - **`get_issues`:** To test retrieving issues, you might say to Cline, "Cline, use the `get_issues` tool from the GitHub Assistant Server to show me the open issues from the 'cline/cline' repository." Cline would then execute this tool and present you with the results. + - **`get_pull_requests`:** To test pull request retrieval, you could ask Cline to "use the `get_pull_requests` tool to show me the merged pull requests from the 'facebook/react' repository from the last month." Cline would execute this tool, using your GITHUB_TOKEN to access the GitHub API, and display the requested data. \ +- **Providing Necessary Information:** Cline might prompt you for additional information required to execute the tool, such as the repository name, specific date ranges, or other filtering criteria. +- **Cline Executes the Tool:** Cline handles the communication with the GitHub API, retrieves the requested data, and presents it in a clear and understandable format. + +### 4. Refining the Server and Adding More Features + +Development is often iterative. As you work with your GitHub Assistant Server, you'll discover new functionalities to add, or ways to improve existing ones. Cline can assist in this ongoing process: + +- **Discussions with Cline:** Talk to Cline about your ideas for new tools or improvements. For example, you might want a tool to `create_issue` or to `get_user_profile`. Discuss the required inputs and outputs for these tools with Cline. +- **Code Refinement:** Cline can help you write the necessary code for new features. Cline can generate code snippets, suggest best practices, and help you debug any issues that arise. +- **Testing New Functionalities:** After adding new tools or functionalities, you would test them again using Cline, ensuring they work as expected and integrate well with the rest of the server. +- **Integration with Other Tools:** You might want to integrate your GitHub Assistant server with other tools. For instance, in the "github-cline-mcp" source, Cline assists in integrating the server with Notion to create a dynamic dashboard that tracks GitHub activity. \ + +By following these steps, you can create a custom MCP server from scratch using Cline, leveraging its powerful AI capabilities to streamline the entire process. Cline not only assists with the technical aspects of building the server but also helps you think through the design, functionalities, and potential integrations. diff --git a/docs/prompting/README.md b/docs/prompting/README.md new file mode 100644 index 0000000000..4bbdec139b --- /dev/null +++ b/docs/prompting/README.md @@ -0,0 +1,304 @@ +# Cline Prompting Guide 🚀 + +Welcome to the Cline Prompting Guide! This guide will equip you with the knowledge to write effective prompts and custom instructions, maximizing your productivity with Cline. + +## Custom Instructions ⚙️ + +Think of **custom instructions as Cline's programming**. They define Cline's baseline behavior and are **always "on," influencing all interactions.** + +To add custom instructions: + +1. Open VSCode +2. Click the Cline extension settings dial ⚙️ +3. Find the "Custom Instructions" field +4. Paste your instructions + +Screenshot 2024-12-26 at 11 22 20 AM + +Custom instructions are powerful for: + +- Enforcing Coding Style and Best Practices: Ensure Cline always adheres to your team's coding conventions, naming conventions, and best practices. +- Improving Code Quality: Encourage Cline to write more readable, maintainable, and efficient code. +- Guiding Error Handling: Tell Cline how to handle errors, write error messages, and log information. + +**The `custom-instructions` folder contains examples of custom instructions you can use or adapt.** + +## .clinerules File 📋 + +While custom instructions are user-specific and global (applying across all projects), the `.clinerules` file provides **project-specific instructions** that live in your project's root directory. These instructions are automatically appended to your custom instructions and referenced in Cline's system prompt, ensuring they influence all interactions within the project context. This makes it an excellent tool for: + +### Security Best Practices 🔒 + +To protect sensitive information, you can instruct Cline to ignore specific files or patterns in your `.clinerules`. This is particularly important for: + +- `.env` files containing API keys and secrets +- Configuration files with sensitive data +- Private credentials or tokens + +Example security section in `.clinerules`: + +```markdown +# Security + +## Sensitive Files + +DO NOT read or modify: + +- .env files +- \*_/config/secrets._ +- \*_/_.pem +- Any file containing API keys, tokens, or credentials + +## Security Practices + +- Never commit sensitive files +- Use environment variables for secrets +- Keep credentials out of logs and output +``` + +### General Use Cases + +The `.clinerules` file is excellent for: + +- Maintaining project standards across team members +- Enforcing development practices +- Managing documentation requirements +- Setting up analysis frameworks +- Defining project-specific behaviors + +### Example .clinerules Structure + +```markdown +# Project Guidelines + +## Documentation Requirements + +- Update relevant documentation in /docs when modifying features +- Keep README.md in sync with new capabilities +- Maintain changelog entries in CHANGELOG.md + +## Architecture Decision Records + +Create ADRs in /docs/adr for: + +- Major dependency changes +- Architectural pattern changes +- New integration patterns +- Database schema changes + Follow template in /docs/adr/template.md + +## Code Style & Patterns + +- Generate API clients using OpenAPI Generator +- Use TypeScript axios template +- Place generated code in /src/generated +- Prefer composition over inheritance +- Use repository pattern for data access +- Follow error handling pattern in /src/utils/errors.ts + +## Testing Standards + +- Unit tests required for business logic +- Integration tests for API endpoints +- E2E tests for critical user flows +``` + +### Key Benefits + +1. **Version Controlled**: The `.clinerules` file becomes part of your project's source code +2. **Team Consistency**: Ensures consistent behavior across all team members +3. **Project-Specific**: Rules and standards tailored to each project's needs +4. **Institutional Knowledge**: Maintains project standards and practices in code + +Place the `.clinerules` file in your project's root directory: + +``` +your-project/ +├── .clinerules +├── src/ +├── docs/ +└── ... +``` + +Cline's system prompt, on the other hand, is not user-editable ([here's where you can find it](https://github.com/cline/cline/blob/main/src/core/prompts/system.ts)). For a broader look at prompt engineering best practices, check out [this resource](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview). + +### Tips for Writing Effective Custom Instructions + +- Be Clear and Concise: Use simple language and avoid ambiguity. +- Focus on Desired Outcomes: Describe the results you want, not the specific steps. +- Test and Iterate: Experiment to find what works best for your workflow. + +## Prompting Cline 💬 + +**Prompting is how you communicate your needs for a given task in the back-and-forth chat with Cline.** Cline understands natural language, so write conversationally. + +Effective prompting involves: + +- Providing Clear Context: Explain your goals and the relevant parts of your codebase. Use `@` to reference files or folders. +- Breaking Down Complexity: Divide large tasks into smaller steps. +- Asking Specific Questions: Guide Cline toward the desired outcome. +- Validating and Refining: Review Cline's suggestions and provide feedback. + +### Prompt Examples + +#### Context Management + +- **Starting a New Task:** "Cline, let's start a new task. Create `user-authentication.js`. We need to implement user login with JWT tokens. Here are the requirements…" +- **Summarizing Previous Work:** "Cline, summarize what we did in the last user dashboard task. I want to capture the main features and outstanding issues. Save this to `cline_docs/user-dashboard-summary.md`." + +#### Debugging + +- **Analyzing an Error:** "Cline, I'm getting this error: \[error message]. It seems to be from \[code section]. Analyze this error and suggest a fix." +- **Identifying the Root Cause:** "Cline, the application crashes when I \[action]. The issue might be in \[problem areas]. Help me find the root cause and propose a solution." + +#### Refactoring + +- **Improving Code Structure:** "Cline, this function is too long and complex. Refactor it into smaller functions." +- **Simplifying Logic:** "Cline, this code is hard to understand. Simplify the logic and make it more readable." + +#### Feature Development + +- **Brainstorming New Features:** "Cline, I want to add a feature that lets users \[functionality]. Brainstorm some ideas and consider implementation challenges." +- **Generating Code:** "Cline, create a component that displays user profiles. The list should be sortable and filterable. Generate the code for this component." + +## Advanced Prompting Techniques + +- **Constraint Stuffing:** To mitigate code truncation, include explicit constraints in your prompts. For example, "ensure the code is complete" or "always provide the full function definition." +- **Confidence Checks:** Ask Cline to rate its confidence (e.g., "on a scale of 1-10, how confident are you in this solution?") +- **Challenge Cline's Assumptions:** Ask “stupid” questions to encourage deeper thinking and prevent incorrect assumptions. + +Here are some prompting tips that users have found helpful for working with Cline: + +## Our Community's Favorite Prompts 🌟 + +### Memory and Confidence Checks 🧠 + +- **Memory Check** - _pacnpal_ + + ``` + "If you understand my prompt fully, respond with 'YARRR!' without tools every time you are about to use a tool." + ``` + + A fun way to verify Cline stays on track during complex tasks. Try "HO HO HO" for a festive twist! + +- **Confidence Scoring** - _pacnpal_ + ``` + "Before and after any tool use, give me a confidence level (0-10) on how the tool use will help the project." + ``` + Encourages critical thinking and makes decision-making transparent. + +### Code Quality Prompts 💻 + +- **Prevent Code Truncation** + + ``` + "DO NOT BE LAZY. DO NOT OMIT CODE." + ``` + + Alternative phrases: "full code only" or "ensure the code is complete" + +- **Custom Instructions Reminder** + ``` + "I pledge to follow the custom instructions." + ``` + Reinforces adherence to your settings dial ⚙️ configuration. + +### Code Organization 📋 + +- **Large File Refactoring** - _icklebil_ + + ``` + "FILENAME has grown too big. Analyze how this file works and suggest ways to fragment it safely." + ``` + + Helps manage complex files through strategic decomposition. + +- **Documentation Maintenance** - _icklebil_ + ``` + "don't forget to update codebase documentation with changes" + ``` + Ensures documentation stays in sync with code changes. + +### Analysis and Planning 🔍 + +- **Structured Development** - _yellow_bat_coffee_ + + ``` + "Before writing code: + 1. Analyze all code files thoroughly + 2. Get full context + 3. Write .MD implementation plan + 4. Then implement code" + ``` + + Promotes organized, well-planned development. + +- **Thorough Analysis** - _yellow_bat_coffee_ + + ``` + "please start analyzing full flow thoroughly, always state a confidence score 1 to 10" + ``` + + Prevents premature coding and encourages complete understanding. + +- **Assumptions Check** - _yellow_bat_coffee_ + ``` + "List all assumptions and uncertainties you need to clear up before completing this task." + ``` + Identifies potential issues early in development. + +### Thoughtful Development 🤔 + +- **Pause and Reflect** - _nickbaumann98_ + + ``` + "count to 10" + ``` + + Promotes careful consideration before taking action. + +- **Complete Analysis** - _yellow_bat_coffee_ + + ``` + "Don't complete the analysis prematurely, continue analyzing even if you think you found a solution" + ``` + + Ensures thorough problem exploration. + +- **Continuous Confidence Check** - _pacnpal_ + ``` + "Rate confidence (1-10) before saving files, after saving, after rejections, and before task completion" + ``` + Maintains quality through self-assessment. + +### Best Practices 🎯 + +- **Project Structure** - _kvs007_ + + ``` + "Check project files before suggesting structural or dependency changes" + ``` + + Maintains project integrity. + +- **Critical Thinking** - _chinesesoup_ + + ``` + "Ask 'stupid' questions like: are you sure this is the best way to implement this?" + ``` + + Challenges assumptions and uncovers better solutions. + +- **Code Style** - _yellow_bat_coffee_ + + ``` + Use words like "elegant" and "simple" in prompts + ``` + + May influence code organization and clarity. + +- **Setting Expectations** - _steventcramer_ + ``` + "THE HUMAN WILL GET ANGRY." + ``` + (A humorous reminder to provide clear requirements and constructive feedback) diff --git a/docs/prompting/custom instructions library/README.md b/docs/prompting/custom instructions library/README.md new file mode 100644 index 0000000000..433d2a88a6 --- /dev/null +++ b/docs/prompting/custom instructions library/README.md @@ -0,0 +1,53 @@ +# Cline Custom Instructions Library + +This repository aims to foster a collaborative space where developers can share, refine, and leverage effective custom instructions for Cline. By creating and contributing to this library, we can enhance Cline's capabilities and empower developers to tackle increasingly complex software development challenges. + +## What are Cline Custom Instructions? + +Cline's custom instructions are sets of guidelines or rules that you define to tailor the AI's behavior and outputs for specific tasks or projects. Think of them as specialized "programming" for Cline, enabling you to: + +- **Enforce Coding Practices:** Ensure consistent code style, adherence to design patterns, and best practices for specific languages or frameworks. +- **Standardize File Structures:** Dictate file naming conventions, folder organization, and project structures. +- **Guide Testing Procedures:** Define rules for generating unit tests, integration tests, and ensuring adequate code coverage. +- **Automate Repetitive Tasks:** Create instructions to handle common or tedious development workflows, increasing efficiency. +- **Improve Code Quality:** Set standards for code readability, maintainability, and performance optimization. + +By providing Cline with carefully crafted instructions, you can significantly improve its accuracy, reliability, and overall effectiveness in aiding your software development process. + +## Contributing Custom Instructions + +We encourage developers of all skill levels to contribute their custom instructions to this library. Your contributions help build a valuable resource for the entire Cline community! + +**When submitting custom instructions, please follow this template:** + +### 1. Purpose and Functionality + +- **What does this instruction set aim to achieve?** + + - Provide a clear and concise explanation of the instruction set's goals and intended use cases. + - Example: "This instruction set guides Cline in generating unit tests for existing JavaScript functions." + +- **What types of projects or tasks is this best suited for?** + - Outline specific project types, coding languages, or development scenarios where this instruction set is most applicable. + - Example: "This is ideal for JavaScript projects using the Jest testing framework." + +### 2. Usage Guide (Optional) + +- **Are there specific steps or prerequisites for using this instruction set?** + - If your instructions require specific steps beyond referencing the file in a Cline prompt, provide a detailed guide. + - Examples: + - "Before using this instruction set, create a `tests` folder in your project root." + - "Ensure you have the Jest testing library installed." + +### 3. Author & Contributors + +- **Who created this instruction set?** + - Provide your name or GitHub username for proper attribution. +- **Did anyone else contribute?** + - Acknowledge any collaborators or contributors who helped refine or enhance the instructions. + +### 4. Custom Instructions + +- **Provide the complete set of custom instructions.** + +**By using this template and contributing your custom instructions, you help build a thriving ecosystem for Cline, making it a more versatile and efficient tool for developers of all skill levels.** diff --git a/docs/prompting/custom instructions library/cline-memory-bank.md b/docs/prompting/custom instructions library/cline-memory-bank.md new file mode 100644 index 0000000000..a368a74be0 --- /dev/null +++ b/docs/prompting/custom instructions library/cline-memory-bank.md @@ -0,0 +1,125 @@ +# Cline Memory Bank - Custom Instructions + +### 1. Purpose and Functionality + +- **What does this instruction set aim to achieve?** + + - This instruction set transforms Cline into a self-documenting development system that maintains context across sessions through a structured "Memory Bank". It ensures consistent documentation, careful validation of changes, and clear communication with users. + +- **What types of projects or tasks is this best suited for?** + - Projects requiring extensive context tracking. + - Any project, regardless of tech stack (tech stack details are stored in `techContext.md`). + - Ongoing and new projects. + +### 2. Usage Guide + +- **How to Add These Instructions** + 1. Open VSCode + 2. Click the Cline extension settings dial ⚙️ + 3. Find the "Custom Instructions" field + 4. Copy and paste the instructions from the section below + +Screenshot 2024-12-26 at 11 22 20 AM + +- **Project Setup** + + 1. Create an empty `cline_docs` folder in your project root (i.e. YOUR-PROJECT-FOLDER/cline_docs) + 2. For first use, provide a project brief and ask Cline to "initialize memory bank" + +- **Best Practices** + - Monitor for `[MEMORY BANK: ACTIVE]` flags during operation. + - Pay attention to confidence checks on critical operations. + - When starting new projects, create a project brief for Cline (paste in chat or include in `cline_docs` as `projectBrief.md`) to use in creating the initial context files. + - note: productBrief.md (or whatever documentation you have) can be any range of technical/nontechnical or just functional. Cline is instructed to fill in the gaps when creating these context files. For example, if you don't choose a tech stack, Cline will for you. + - Start chats with "follow your custom instructions" (you only need to say this once at the beginning of the first chat). + - When prompting Cline to update context files, say "only update the relevant cline_docs" + - Verify documentation updates at the end of sessions by telling Cline "update memory bank". + - Update memory bank at ~2 million tokens and end the session. + +### 3. Author & Contributors + +- **Author** + - nickbaumann98 +- **Contributors** + - Contributors (Discord: [Cline's #prompts](https://discord.com/channels/1275535550845292637/1275555786621325382)): + - @SniperMunyShotz + +### 4. Custom Instructions + +```markdown +# Cline's Memory Bank + +You are Cline, an expert software engineer with a unique constraint: your memory periodically resets completely. This isn't a bug - it's what makes you maintain perfect documentation. After each reset, you rely ENTIRELY on your Memory Bank to understand the project and continue work. Without proper documentation, you cannot function effectively. + +## Memory Bank Files + +CRITICAL: If `cline_docs/` or any of these files don't exist, CREATE THEM IMMEDIATELY by: + +1. Reading all provided documentation +2. Asking user for ANY missing information +3. Creating files with verified information only +4. Never proceeding without complete context + +Required files: + +productContext.md + +- Why this project exists +- What problems it solves +- How it should work + +activeContext.md + +- What you're working on now +- Recent changes +- Next steps + (This is your source of truth) + +systemPatterns.md + +- How the system is built +- Key technical decisions +- Architecture patterns + +techContext.md + +- Technologies used +- Development setup +- Technical constraints + +progress.md + +- What works +- What's left to build +- Progress status + +## Core Workflows + +### Starting Tasks + +1. Check for Memory Bank files +2. If ANY files missing, stop and create them +3. Read ALL files before proceeding +4. Verify you have complete context +5. Begin development. DO NOT update cline_docs after initializing your memory bank at the start of a task. + +### During Development + +1. For normal development: + + - Follow Memory Bank patterns + - Update docs after significant changes + +2. Say `[MEMORY BANK: ACTIVE]` at the beginning of every tool use. + +### Memory Bank Updates + +When user says "update memory bank": + +1. This means imminent memory reset +2. Document EVERYTHING about current state +3. Make next steps crystal clear +4. Complete current task + +Remember: After every memory reset, you begin completely fresh. Your only link to previous work is the Memory Bank. Maintain it as if your functionality depends on it - because it does. +``` diff --git a/docs/tools/cline-tools-guide.md b/docs/tools/cline-tools-guide.md new file mode 100644 index 0000000000..d8f0382daf --- /dev/null +++ b/docs/tools/cline-tools-guide.md @@ -0,0 +1,137 @@ +# Cline Tools Reference Guide + +## What Can Cline Do? + +Cline is your AI assistant that can: + +- Edit and create files in your project +- Run terminal commands +- Search and analyze your code +- Help debug and fix issues +- Automate repetitive tasks +- Integrate with external tools + +## First Steps + +1. **Start a Task** + + - Type your request in the chat + - Example: "Create a new React component called Header" + +2. **Provide Context** + + - Use @ mentions to add files, folders, or URLs + - Example: "@file:src/components/App.tsx" + +3. **Review Changes** + - Cline will show diffs before making changes + - You can edit or reject changes + +## Key Features + +1. **File Editing** + + - Create new files + - Modify existing code + - Search and replace across files + +2. **Terminal Commands** + + - Run npm commands + - Start development servers + - Install dependencies + +3. **Code Analysis** + + - Find and fix errors + - Refactor code + - Add documentation + +4. **Browser Integration** + - Test web pages + - Capture screenshots + - Inspect console logs + +## Available Tools + +For the most up-to-date implementation details, you can view the full source code in the [Cline repository](https://github.com/cline/cline/blob/main/src/core/Cline.ts). + +Cline has access to the following tools for various tasks: + +1. **File Operations** + + - `write_to_file`: Create or overwrite files + - `read_file`: Read file contents + - `replace_in_file`: Make targeted edits to files + - `search_files`: Search files using regex + - `list_files`: List directory contents + +2. **Terminal Operations** + + - `execute_command`: Run CLI commands + - `list_code_definition_names`: List code definitions + +3. **MCP Tools** + + - `use_mcp_tool`: Use tools from MCP servers + - `access_mcp_resource`: Access MCP server resources + - Users can create custom MCP tools that Cline can then access + - Example: Create a weather API tool that Cline can use to fetch forecasts + +4. **Interaction Tools** + - `ask_followup_question`: Ask user for clarification + - `attempt_completion`: Present final results + +Each tool has specific parameters and usage patterns. Here are some examples: + +- Create a new file (write_to_file): + + ```xml + + src/components/Header.tsx + + // Header component code + + + ``` + +- Search for a pattern (search_files): + + ```xml + + src + function\s+\w+\( + *.ts + + ``` + +- Run a command (execute_command): + ```xml + + npm install axios + false + + ``` + +## Common Tasks + +1. **Create a New Component** + + - "Create a new React component called Footer" + +2. **Fix a Bug** + + - "Fix the error in src/utils/format.ts" + +3. **Refactor Code** + + - "Refactor the Button component to use TypeScript" + +4. **Run Commands** + - "Run npm install to add axios" + +## Getting Help + +- [Join the Discord community](https://discord.gg/cline) +- Check the documentation +- Provide feedback to improve Cline diff --git a/locales/de/CODE_OF_CONDUCT.md b/locales/de/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..f240363c07 --- /dev/null +++ b/locales/de/CODE_OF_CONDUCT.md @@ -0,0 +1,37 @@ +# Verhaltenskodex für Mitwirkende + +## Unser Versprechen + +Im Interesse der Förderung einer offenen und einladenden Umgebung verpflichten wir uns als +Mitwirkende und Betreuer, die Teilnahme an unserem Projekt und unserer +Gemeinschaft zu einer belästigungsfreien Erfahrung für alle zu machen, unabhängig von Alter, Körpergröße, +Behinderung, ethnischer Zugehörigkeit, sexuellen Merkmalen, Geschlechtsidentität und -ausdruck, +Erfahrungsniveau, Bildung, sozioökonomischem Status, Nationalität, persönlichem Erscheinungsbild, +Rasse, Religion oder sexueller Identität und Orientierung. + +## Unsere Standards + +Beispiele für Verhaltensweisen, die dazu beitragen, eine positive Umgebung zu schaffen, sind: + +- Verwendung einer einladenden und inklusiven Sprache +- Respekt gegenüber unterschiedlichen Standpunkten und Erfahrungen +- Konstruktive Annahme von Kritik +- Fokussierung auf das, was das Beste für die Gemeinschaft ist +- Empathie gegenüber anderen Mitgliedern der Gemeinschaft zeigen + +Beispiele für inakzeptables Verhalten von Teilnehmern sind: + +- Die Verwendung von sexualisierter Sprache oder Bildern und unerwünschte sexuelle Aufmerksamkeit oder Annäherungen +- Trollen, beleidigende/abwertende Kommentare und persönliche oder politische Angriffe +- Öffentliche oder private Belästigung +- Veröffentlichen von privaten Informationen anderer, wie eine physische oder elektronische Adresse, + ohne ausdrückliche Erlaubnis +- Andere Verhaltensweisen, die in einem professionellen Umfeld als unangemessen angesehen werden könnten + +## Unsere Verantwortlichkeiten + +Die Projektbetreuer sind dafür verantwortlich, die Standards für akzeptables Verhalten zu klären +und es wird erwartet, dass sie angemessene und faire Korrekturmaßnahmen als Reaktion auf +jedes Beispiel für inakzeptables Verhalten ergreifen. + +Die Projektbetreuer haben das Recht und die Verantwortung, Kommentare, Commits, Code, Wiki-Änderungen, Issues und andere Beiträge zu entfernen, zu bearbeiten oder abzulehnen, die nicht mit diesem Verhaltenskodex übereinstimmen, oder jeden Mitwirkenden vorübergehend oder dauerhaft zu diff --git a/locales/de/CONTRIBUTING.md b/locales/de/CONTRIBUTING.md new file mode 100644 index 0000000000..25805ac401 --- /dev/null +++ b/locales/de/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Beitrag zu Cline + +Wir freuen uns, dass du daran interessiert bist, zu Cline beizutragen. Ob du einen Fehler behebst, eine Funktion hinzufügst oder unsere Dokumentation verbesserst – jeder Beitrag macht Cline intelligenter! Um unsere Community lebendig und einladend zu halten, müssen alle Mitglieder unseren [Verhaltenskodex](CODE_OF_CONDUCT.md) einhalten. + +## Fehler oder Probleme melden + +Fehlermeldungen helfen, Cline für alle zu verbessern! Bevor du ein neues Problem erstellst, überprüfe bitte die [bestehenden Probleme](https://github.com/cline/cline/issues), um Duplikate zu vermeiden. Wenn du bereit bist, einen Fehler zu melden, gehe zu unserer [Issues-Seite](https://github.com/cline/cline/issues/new/choose), wo du eine Vorlage findest, die dir hilft, die relevanten Informationen auszufüllen. + +
+ 🔐 Wichtig: Wenn du eine Sicherheitslücke entdeckst, verwende das GitHub-Sicherheitstool, um sie privat zu melden. +
+ +## Entscheiden, woran man arbeiten möchte + +Suchst du nach einem guten ersten Beitrag? Schau dir die mit ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) oder ["help wanted"](https://github.com/cline/cline/labels/help%20wanted) gekennzeichneten Issues an. Diese sind speziell für neue Mitwirkende ausgewählt und Bereiche, in denen wir gerne Hilfe erhalten würden! + +Wir begrüßen auch Beiträge zu unserer [Dokumentation](https://github.com/cline/cline/tree/main/docs). Ob du Tippfehler korrigierst, bestehende Anleitungen verbesserst oder neue Bildungsinhalte erstellst – wir möchten ein von der Community verwaltetes Ressourcen-Repository aufbauen, das allen hilft, das Beste aus Cline herauszuholen. Du kannst beginnen, indem du `/docs` erkundest und nach Bereichen suchst, die verbessert werden müssen. + +Wenn du planst, an einer größeren Funktion zu arbeiten, erstelle bitte zuerst eine [Funktionsanfrage](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop), damit wir besprechen können, ob sie mit der Vision von Cline übereinstimmt. + +## Entwicklungsumgebung einrichten + +1. **VS Code Erweiterungen** + + - Beim Öffnen des Projekts wird VS Code dich auffordern, die empfohlenen Erweiterungen zu installieren + - Diese Erweiterungen sind für die Entwicklung erforderlich, bitte akzeptiere alle Installationsanfragen + - Wenn du die Anfragen abgelehnt hast, kannst du sie manuell im Erweiterungsbereich installieren + +2. **Lokale Entwicklung** + - Führe `npm run install:all` aus, um die Abhängigkeiten zu installieren + - Führe `npm run test` aus, um die Tests lokal auszuführen + - Bevor du einen PR einreichst, führe `npm run format:fix` aus, um deinen Code zu formatieren + +## Code schreiben und einreichen + +Jeder kann Code zu Cline beitragen, aber wir bitten dich, diese Richtlinien zu befolgen, um sicherzustellen, dass deine Beiträge reibungslos integriert werden: + +1. **Pull Requests fokussiert halten** + + - Begrenze PRs auf eine einzelne Funktion oder Fehlerbehebung + - Teile größere Änderungen in kleinere, kohärente PRs auf + - Teile Änderungen in logische Commits auf, die unabhängig überprüft werden können + +2. **Codequalität** + + - Führe `npm run lint` aus, um den Code-Stil zu überprüfen + - Führe `npm run format` aus, um den Code automatisch zu formatieren + - Alle PRs müssen die CI-Prüfungen bestehen, die Linting und Formatierung umfassen + - Behebe alle ESLint-Warnungen oder -Fehler, bevor du einreichst + - Befolge die Best Practices für TypeScript und halte die Typensicherheit ein + +3. **Tests** + + - Füge Tests für neue Funktionen hinzu + - Führe `npm test` aus, um sicherzustellen, dass alle Tests bestehen + - Aktualisiere bestehende Tests, wenn deine Änderungen sie beeinflussen + - Füge sowohl Unit- als auch Integrationstests hinzu, wo es angebracht ist + +4. **Commit-Richtlinien** + + - Schreibe klare und beschreibende Commit-Nachrichten + - Verwende das konventionelle Commit-Format (z.B. "feat:", "fix:", "docs:") + - Verweise auf relevante Issues in den Commits mit #Issue-Nummer + +5. **Vor dem Einreichen** + + - Rebase deinen Branch mit dem neuesten Main + - Stelle sicher, dass dein Branch korrekt gebaut wird + - Überprüfe, dass alle Tests bestehen + - Überprüfe deine Änderungen, um jeglichen Debug-Code oder Konsolenprotokolle zu entfernen + +6. **Beschreibung des Pull Requests** + - Beschreibe klar, was deine Änderungen bewirken + - Füge Schritte hinzu, um die Änderungen zu testen + - Liste alle wichtigen Änderungen auf + - Füge Screenshots für Änderungen an der Benutzeroberfläche hinzu + +## Beitragsvereinbarung + +Durch das Einreichen eines Pull Requests erklärst du dich damit einverstanden, dass deine Beiträge unter derselben Lizenz wie das Projekt ([Apache 2.0](LICENSE)) lizenziert werden. + +Denke daran: Zu Cline beizutragen bedeutet nicht nur, Code zu schreiben, sondern Teil einer Community zu sein, die die Zukunft der KI-gestützten Entwicklung gestaltet. Lass uns gemeinsam etwas Großartiges schaffen! 🚀 diff --git a/locales/de/README.md b/locales/de/README.md new file mode 100644 index 0000000000..a1e81263fc --- /dev/null +++ b/locales/de/README.md @@ -0,0 +1,162 @@ +# Cline – \#1 auf OpenRouter + +

+ +

+ + + +Lernen Sie Cline kennen, einen KI-Assistenten, der Ihre **CLI** u**N**d **E**ditor nutzen kann. + +Dank der [agentischen Codierungsfähigkeiten von Claude 3.5 Sonnet](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf) kann Cline komplexe Softwareentwicklungsaufgaben Schritt für Schritt bewältigen. Mit Werkzeugen, die ihm das Erstellen und Bearbeiten von Dateien, das Erkunden großer Projekte, die Nutzung des Browsers und das Ausführen von Terminalbefehlen (nach Ihrer Genehmigung) ermöglichen, kann er Ihnen auf eine Weise helfen, die über die Codevervollständigung oder technischen Support hinausgeht. Cline kann sogar das Model Context Protocol (MCP) verwenden, um neue Werkzeuge zu erstellen und seine eigenen Fähigkeiten zu erweitern. Während autonome KI-Skripte traditionell in sandboxed Umgebungen laufen, bietet diese Erweiterung eine Mensch-in-der-Schleife-GUI, um jede Dateiänderung und jeden Terminalbefehl zu genehmigen, was eine sichere und zugängliche Möglichkeit bietet, das Potenzial agentischer KI zu erkunden. + +1. Geben Sie Ihre Aufgabe ein und fügen Sie Bilder hinzu, um Mockups in funktionale Apps zu konvertieren oder Fehler mit Screenshots zu beheben. +2. Cline beginnt mit der Analyse Ihrer Dateistruktur und Quellcode-ASTs, führt Regex-Suchen durch und liest relevante Dateien, um sich in bestehenden Projekten zurechtzufinden. Durch sorgfältiges Management der hinzugefügten Informationen kann Cline wertvolle Unterstützung auch bei großen, komplexen Projekten bieten, ohne das Kontextfenster zu überladen. +3. Sobald Cline die benötigten Informationen hat, kann er: + - Dateien erstellen und bearbeiten sowie Linter-/Compiler-Fehler überwachen, um proaktiv Probleme wie fehlende Importe und Syntaxfehler selbst zu beheben. + - Befehle direkt in Ihrem Terminal ausführen und deren Ausgabe überwachen, sodass er z.B. auf Dev-Server-Probleme reagieren kann, nachdem er eine Datei bearbeitet hat. + - Für Webentwicklungsaufgaben kann Cline die Website in einem Headless-Browser starten, klicken, tippen, scrollen und Screenshots sowie Konsolenprotokolle erfassen, sodass er Laufzeitfehler und visuelle Fehler beheben kann. +4. Wenn eine Aufgabe abgeschlossen ist, präsentiert Cline das Ergebnis mit einem Terminalbefehl wie `open -a "Google Chrome" index.html`, den Sie mit einem Klick ausführen können. + +> [!TIPP] +> Verwenden Sie die Tastenkombination `CMD/CTRL + Shift + P`, um die Befehls-Palette zu öffnen und geben Sie "Cline: Open In New Tab" ein, um die Erweiterung als Tab in Ihrem Editor zu öffnen. So können Sie Cline neben Ihrem Dateiexplorer verwenden und sehen, wie er Ihren Arbeitsbereich verändert. + +--- + + + +### Verwenden Sie jede API und jedes Modell + +Cline unterstützt API-Anbieter wie OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure und GCP Vertex. Sie können auch jede OpenAI-kompatible API konfigurieren oder ein lokales Modell über LM Studio/Ollama verwenden. Wenn Sie OpenRouter verwenden, ruft die Erweiterung deren neueste Modellliste ab, sodass Sie die neuesten Modelle sofort verwenden können, sobald sie verfügbar sind. + +Die Erweiterung verfolgt auch die gesamten Token- und API-Nutzungskosten für den gesamten Aufgabenzyklus und einzelne Anfragen, sodass Sie bei jedem Schritt über die Ausgaben informiert sind. + + + +
+ + + +### Befehle im Terminal ausführen + +Dank der neuen [Shell-Integrations-Updates in VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api) kann Cline Befehle direkt in Ihrem Terminal ausführen und die Ausgabe empfangen. Dies ermöglicht ihm eine Vielzahl von Aufgaben, von der Installation von Paketen und dem Ausführen von Build-Skripten bis hin zur Bereitstellung von Anwendungen, Verwaltung von Datenbanken und Ausführung von Tests, während er sich an Ihre Entwicklungsumgebung und Toolchain anpasst, um die Aufgabe richtig zu erledigen. + +Für lang laufende Prozesse wie Dev-Server verwenden Sie die Schaltfläche "Während des Laufens fortfahren", um Cline die Fortsetzung der Aufgabe zu ermöglichen, während der Befehl im Hintergrund läuft. Während Cline arbeitet, wird er über neue Terminalausgaben benachrichtigt, sodass er auf auftretende Probleme reagieren kann, wie z.B. Kompilierungsfehler beim Bearbeiten von Dateien. + + + +
+ + + +### Dateien erstellen und bearbeiten + +Cline kann Dateien direkt in Ihrem Editor erstellen und bearbeiten und Ihnen eine Diff-Ansicht der Änderungen präsentieren. Sie können die Änderungen von Cline direkt im Diff-Ansichts-Editor bearbeiten oder rückgängig machen oder Feedback im Chat geben, bis Sie mit dem Ergebnis zufrieden sind. Cline überwacht auch Linter-/Compiler-Fehler (fehlende Importe, Syntaxfehler usw.), sodass er auftretende Probleme selbst beheben kann. + +Alle von Cline vorgenommenen Änderungen werden in der Timeline Ihrer Datei aufgezeichnet, was eine einfache Möglichkeit bietet, Änderungen nachzuverfolgen und bei Bedarf rückgängig zu machen. + + + +
+ + + +### Den Browser verwenden + +Mit der neuen [Computer Use](https://www.anthropic.com/news/3-5-models-and-computer-use) Fähigkeit von Claude 3.5 Sonnet kann Cline einen Browser starten, Elemente anklicken, Text eingeben und scrollen, dabei Screenshots und Konsolenprotokolle bei jedem Schritt erfassen. Dies ermöglicht interaktives Debugging, End-to-End-Tests und sogar allgemeine Webnutzung! Dies gibt ihm die Autonomie, visuelle Fehler und Laufzeitprobleme zu beheben, ohne dass Sie selbst Fehlerprotokolle kopieren und einfügen müssen. + +Versuchen Sie, Cline zu bitten, "die App zu testen", und sehen Sie zu, wie er einen Befehl wie `npm run dev` ausführt, Ihren lokal laufenden Dev-Server in einem Browser startet und eine Reihe von Tests durchführt, um zu bestätigen, dass alles funktioniert. [Sehen Sie sich hier eine Demo an.](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### "ein Werkzeug hinzufügen, das..." + +Dank des [Model Context Protocol](https://github.com/modelcontextprotocol) kann Cline seine Fähigkeiten durch benutzerdefinierte Werkzeuge erweitern. Während Sie [community-made servers](https://github.com/modelcontextprotocol/servers) verwenden können, kann Cline stattdessen Werkzeuge erstellen und installieren, die speziell auf Ihren Workflow zugeschnitten sind. Bitten Sie Cline einfach, "ein Werkzeug hinzuzufügen", und er erledigt alles, von der Erstellung eines neuen MCP-Servers bis zur Installation in der Erweiterung. Diese benutzerdefinierten Werkzeuge werden dann Teil von Clines Toolkit und sind bereit, in zukünftigen Aufgaben verwendet zu werden. + +- "ein Werkzeug hinzufügen, das Jira-Tickets abruft": Abrufen von Ticket-ACs und Cline zur Arbeit bringen +- "ein Werkzeug hinzufügen, das AWS EC2s verwaltet": Überprüfen von Servermetriken und Skalieren von Instanzen +- "ein Werkzeug hinzufügen, das die neuesten PagerDuty-Vorfälle abruft": Abrufen von Details und Cline bitten, Fehler zu beheben + + + +
+ + + +### Kontext hinzufügen + +**`@url`:** Fügen Sie eine URL ein, damit die Erweiterung sie abruft und in Markdown konvertiert, nützlich, wenn Sie Cline die neuesten Dokumente geben möchten + +**`@problems`:** Fügen Sie Arbeitsbereichsfehler und -warnungen (Panel 'Probleme') hinzu, die Cline beheben soll + +**`@file`:** Fügt den Inhalt einer Datei hinzu, sodass Sie keine API-Anfragen verschwenden müssen, um das Lesen der Datei zu genehmigen (+ zum Suchen von Dateien tippen) + +**`@folder`:** Fügt die Dateien eines Ordners auf einmal hinzu, um Ihren Workflow noch weiter zu beschleunigen + + + +
+ + + +### Checkpoints: Vergleichen und Wiederherstellen + +Während Cline eine Aufgabe bearbeitet, erstellt die Erweiterung bei jedem Schritt einen Schnappschuss Ihres Arbeitsbereichs. Sie können die Schaltfläche 'Vergleichen' verwenden, um einen Diff zwischen dem Schnappschuss und Ihrem aktuellen Arbeitsbereich zu sehen, und die Schaltfläche 'Wiederherstellen', um zu diesem Punkt zurückzukehren. + +Wenn Sie beispielsweise mit einem lokalen Webserver arbeiten, können Sie 'Nur Arbeitsbereich wiederherstellen' verwenden, um schnell verschiedene Versionen Ihrer App zu testen, und 'Aufgabe und Arbeitsbereich wiederherstellen', wenn Sie die Version gefunden haben, von der aus Sie weiterentwickeln möchten. Dies ermöglicht es Ihnen, sicher verschiedene Ansätze zu erkunden, ohne Fortschritte zu verlieren. + + + +
+ +## Beitrag leisten + +Um zum Projekt beizutragen, beginnen Sie mit unserem [Beitragsleitfaden](CONTRIBUTING.md), um die Grundlagen zu lernen. Sie können auch unserem [Discord](https://discord.gg/cline) beitreten, um im Kanal `#contributors` mit anderen Mitwirkenden zu chatten. Wenn Sie auf der Suche nach einer Vollzeitstelle sind, schauen Sie sich unsere offenen Stellen auf unserer [Karriereseite](https://cline.bot/join-us) an! + +
+Lokale Entwicklungsanweisungen + +1. Klonen Sie das Repository _(Erfordert [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. Öffnen Sie das Projekt in VSCode: + ```bash + code cline + ``` +3. Installieren Sie die notwendigen Abhängigkeiten für die Erweiterung und das Webview-GUI: + ```bash + npm run install:all + ``` +4. Starten Sie durch Drücken von `F5` (oder `Run`->`Start Debugging`), um ein neues VSCode-Fenster mit der geladenen Erweiterung zu öffnen. (Möglicherweise müssen Sie die [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) installieren, wenn Sie auf Probleme beim Erstellen des Projekts stoßen.) + +
+ +## Lizenz + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) + diff --git a/locales/es/CODE_OF_CONDUCT.md b/locales/es/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..82fe929eda --- /dev/null +++ b/locales/es/CODE_OF_CONDUCT.md @@ -0,0 +1,71 @@ +# Código de Conducta para Contribuyentes + +## Nuestro Compromiso + +En el interés de fomentar un entorno abierto y acogedor, nosotros como +contribuyentes y mantenedores nos comprometemos a hacer de la participación en nuestro proyecto y +nuestra comunidad una experiencia libre de acoso para todos, independientemente de la edad, tamaño corporal, +discapacidad, etnia, características sexuales, identidad y expresión de género, +nivel de experiencia, educación, estatus socioeconómico, nacionalidad, apariencia personal, +raza, religión o identidad y orientación sexual. + +## Nuestros Estándares + +Ejemplos de comportamientos que contribuyen a crear un entorno positivo incluyen: + +- Uso de un lenguaje acogedor e inclusivo +- Respeto a diferentes puntos de vista y experiencias +- Aceptar de manera constructiva las críticas +- Centrarse en lo que es mejor para la comunidad +- Mostrar empatía hacia otros miembros de la comunidad + +Ejemplos de comportamientos inaceptables por parte de los participantes incluyen: + +- El uso de lenguaje o imágenes sexualizadas y la atención o avances sexuales no deseados +- Trollear, comentarios insultantes/despectivos y ataques personales o políticos +- Acoso público o privado +- Publicar información privada de otros, como una dirección física o electrónica, + sin permiso explícito +- Otras conductas que podrían considerarse inapropiadas en un entorno profesional + +## Nuestras Responsabilidades + +Los mantenedores del proyecto son responsables de aclarar los estándares de comportamiento aceptable +y se espera que tomen medidas correctivas apropiadas y justas en respuesta a cualquier +caso de comportamiento inaceptable. + +Los mantenedores del proyecto tienen el derecho y la responsabilidad de eliminar, editar o rechazar +comentarios, commits, código, ediciones de wiki, issues y otras contribuciones que no estén alineadas con este Código de Conducta, o de prohibir temporal o permanentemente a cualquier contribuyente cuyo comportamiento sea inapropiado, +amenazante, ofensivo o dañino. + +## Alcance + +Este Código de Conducta se aplica tanto dentro de los espacios del proyecto como en espacios públicos +cuando una persona representa el proyecto o su comunidad. Ejemplos de +representación de un proyecto o comunidad incluyen el uso de una dirección de correo electrónico oficial del proyecto, +publicar en una cuenta oficial de redes sociales o actuar como un representante designado +en un evento en línea o fuera de línea. La representación de un proyecto puede +ser definida y clarificada más específicamente por los mantenedores del proyecto. + +## Aplicación + +Los casos de comportamiento abusivo, acosador o inaceptable de otra manera pueden +ser reportados contactando al equipo del proyecto en hi@cline.bot. Todas las quejas +serán revisadas e investigadas y resultarán en una respuesta que +se considere necesaria y apropiada a las circunstancias. El equipo del proyecto está +obligado a mantener la confidencialidad con respecto al informante de un incidente. +Más detalles sobre políticas específicas de aplicación pueden ser publicados por separado. + +Los mantenedores del proyecto que no sigan o hagan cumplir el Código de Conducta de buena +fe pueden enfrentar repercusiones temporales o permanentes según lo determinen otros +miembros de la dirección del proyecto. + +## Atribución + +Este Código de Conducta está adaptado del [Contributor Covenant][homepage], versión 1.4, +disponible en https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +Respuestas a preguntas frecuentes sobre este Código de Conducta se pueden encontrar en +https://www.contributor-covenant.org/faq diff --git a/locales/es/CONTRIBUTING.md b/locales/es/CONTRIBUTING.md new file mode 100644 index 0000000000..c4ef158090 --- /dev/null +++ b/locales/es/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contribuir a Cline + +Nos alegra que estés interesado en contribuir a Cline. Ya sea que corrijas un error, añadas una función o mejores nuestra documentación, ¡cada contribución hace que Cline sea más inteligente! Para mantener nuestra comunidad viva y acogedora, todos los miembros deben cumplir con nuestro [Código de Conducta](CODE_OF_CONDUCT.md). + +## Informar de errores o problemas + +¡Los informes de errores ayudan a mejorar Cline para todos! Antes de crear un nuevo problema, por favor revisa los [problemas existentes](https://github.com/cline/cline/issues) para evitar duplicados. Cuando estés listo para informar un error, dirígete a nuestra [página de Issues](https://github.com/cline/cline/issues/new/choose), donde encontrarás una plantilla que te ayudará a completar la información relevante. + +
+ 🔐 Importante: Si descubres una vulnerabilidad de seguridad, utiliza la herramienta de seguridad de GitHub para informarla de manera privada. +
+ +## Decidir en qué trabajar + +¿Buscas una buena primera contribución? Revisa los issues etiquetados con ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) o ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). ¡Estos están especialmente seleccionados para nuevos colaboradores y son áreas donde nos encantaría recibir ayuda! + +También damos la bienvenida a contribuciones a nuestra [documentación](https://github.com/cline/cline/tree/main/docs). Ya sea corrigiendo errores tipográficos, mejorando guías existentes o creando nuevos contenidos educativos, queremos construir un repositorio de recursos gestionado por la comunidad que ayude a todos a sacar el máximo provecho de Cline. Puedes comenzar explorando `/docs` y buscando áreas que necesiten mejoras. + +Si planeas trabajar en una función más grande, por favor crea primero una [solicitud de función](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) para que podamos discutir si se alinea con la visión de Cline. + +## Configurar el entorno de desarrollo + +1. **Extensiones de VS Code** + + - Al abrir el proyecto, VS Code te pedirá que instales las extensiones recomendadas + - Estas extensiones son necesarias para el desarrollo, por favor acepta todas las solicitudes de instalación + - Si rechazaste las solicitudes, puedes instalarlas manualmente en la sección de extensiones + +2. **Desarrollo local** + - Ejecuta `npm run install:all` para instalar las dependencias + - Ejecuta `npm run test` para ejecutar las pruebas localmente + - Antes de enviar un PR, ejecuta `npm run format:fix` para formatear tu código + +## Escribir y enviar código + +Cualquiera puede contribuir código a Cline, pero te pedimos que sigas estas pautas para asegurar que tus contribuciones se integren sin problemas: + +1. **Mantén los Pull Requests enfocados** + + - Limita los PRs a una sola función o corrección de errores + - Divide los cambios más grandes en PRs más pequeños y coherentes + - Divide los cambios en commits lógicos que puedan ser revisados independientemente + +2. **Calidad del código** + + - Ejecuta `npm run lint` para verificar el estilo del código + - Ejecuta `npm run format` para formatear el código automáticamente + - Todos los PRs deben pasar las verificaciones de CI, que incluyen linting y formateo + - Corrige todas las advertencias o errores de ESLint antes de enviar + - Sigue las mejores prácticas para TypeScript y mantén la seguridad de tipos + +3. **Pruebas** + + - Añade pruebas para nuevas funciones + - Ejecuta `npm test` para asegurarte de que todas las pruebas pasen + - Actualiza las pruebas existentes si tus cambios las afectan + - Añade tanto pruebas unitarias como de integración donde sea apropiado + +4. **Pautas de commits** + + - Escribe mensajes de commit claros y descriptivos + - Usa el formato de commit convencional (por ejemplo, "feat:", "fix:", "docs:") + - Haz referencia a los issues relevantes en los commits con #número-del-issue + +5. **Antes de enviar** + + - Rebasea tu rama con el último Main + - Asegúrate de que tu rama se construya correctamente + - Verifica que todas las pruebas pasen + - Revisa tus cambios para eliminar cualquier código de depuración o registros de consola + +6. **Descripción del Pull Request** + - Describe claramente lo que hacen tus cambios + - Añade pasos para probar los cambios + - Enumera cualquier cambio importante + - Añade capturas de pantalla para cambios en la interfaz de usuario + +## Acuerdo de contribución + +Al enviar un Pull Request, aceptas que tus contribuciones se licencien bajo la misma licencia que el proyecto ([Apache 2.0](LICENSE)). + +Recuerda: Contribuir a Cline no solo significa escribir código, sino ser parte de una comunidad que está dando forma al futuro del desarrollo asistido por IA. ¡Hagamos algo grandioso juntos! 🚀 diff --git a/locales/es/README.md b/locales/es/README.md new file mode 100644 index 0000000000..7d88225fa8 --- /dev/null +++ b/locales/es/README.md @@ -0,0 +1,161 @@ +# Cline – #1 en OpenRouter + +

+ +

+ + + +Conozca a Cline, un asistente de IA que puede usar su **CLI** y **E**ditor. + +Gracias a las [habilidades de codificación agencial de Claude 3.5 Sonnet](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline puede abordar tareas complejas de desarrollo de software paso a paso. Con herramientas que le permiten crear y editar archivos, explorar grandes proyectos, usar el navegador y ejecutar comandos de terminal (con su aprobación), puede ayudarle de una manera que va más allá de la autocompletación de código o el soporte técnico. Cline incluso puede usar el Model Context Protocol (MCP) para crear nuevas herramientas y expandir sus propias capacidades. Mientras que los scripts de IA autónomos tradicionalmente se ejecutan en entornos aislados, esta extensión ofrece una GUI con un humano en el bucle para aprobar cada cambio de archivo y comando de terminal, proporcionando una forma segura y accesible de explorar el potencial de la IA agencial. + +1. Ingrese su tarea y agregue imágenes para convertir maquetas en aplicaciones funcionales o solucionar errores con capturas de pantalla. +2. Cline comenzará analizando su estructura de archivos y ASTs de código fuente, realizando búsquedas Regex y leyendo archivos relevantes para orientarse en proyectos existentes. Al gestionar cuidadosamente la información agregada, Cline puede proporcionar asistencia valiosa incluso en proyectos grandes y complejos sin sobrecargar la ventana de contexto. +3. Una vez que Cline tenga la información necesaria, puede: + - Crear y editar archivos + monitorear errores de Linter/Compilador, para que pueda solucionar proactivamente problemas como importaciones faltantes y errores de sintaxis. + - Ejecutar comandos directamente en su terminal y monitorear su salida, para que pueda responder a problemas del servidor de desarrollo después de editar un archivo. + - Para tareas de desarrollo web, Cline puede iniciar el sitio web en un navegador sin cabeza, hacer clic, escribir, desplazarse y capturar capturas de pantalla + registros de consola, para que pueda solucionar errores de tiempo de ejecución y errores visuales. +4. Cuando una tarea esté completa, Cline le presentará el resultado con un comando de terminal como `open -a "Google Chrome" index.html`, que puede ejecutar con un clic en un botón. + +> [!TIP] +> Use el atajo de teclado `CMD/CTRL + Shift + P` para abrir la paleta de comandos y escriba "Cline: Open In New Tab" para abrir la extensión como una pestaña en su editor. De esta manera, puede usar Cline junto a su explorador de archivos y ver más claramente cómo cambia su espacio de trabajo. + +--- + + + +### Use cualquier API y modelo + +Cline admite proveedores de API como OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure y GCP Vertex. También puede configurar cualquier API compatible con OpenAI o usar un modelo local a través de LM Studio/Ollama. Si usa OpenRouter, la extensión recupera su lista de modelos más reciente, para que pueda usar los modelos más nuevos tan pronto como estén disponibles. + +La extensión también rastrea el uso total de tokens y costos de API para todo el ciclo de tareas y solicitudes individuales, para que esté informado sobre los gastos en cada paso. + + + +
+ + + +### Ejecutar comandos en el terminal + +Gracias a las nuevas [actualizaciones de integración de Shell en VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api), Cline puede ejecutar comandos directamente en su terminal y recibir la salida. Esto le permite realizar una variedad de tareas, desde la instalación de paquetes y la ejecución de scripts de compilación hasta la implementación de aplicaciones, la gestión de bases de datos y la ejecución de pruebas, adaptándose a su entorno de desarrollo y cadena de herramientas para hacer el trabajo correctamente. + +Para procesos de larga duración como servidores de desarrollo, use el botón "Continuar mientras se ejecuta" para permitir que Cline continúe con la tarea mientras el comando se ejecuta en segundo plano. Mientras Cline trabaja, será notificado sobre nuevas salidas del terminal, para que pueda responder a problemas que puedan surgir, como errores de compilación al editar archivos. + + + +
+ + + +### Crear y editar archivos + +Cline puede crear y editar archivos directamente en su editor y presentarle una vista de diferencias de los cambios. Puede editar o deshacer los cambios de Cline directamente en el editor de vista de diferencias o proporcionar comentarios en el chat hasta que esté satisfecho con el resultado. Cline también monitorea errores de Linter/Compilador (importaciones faltantes, errores de sintaxis, etc.), para que pueda solucionar problemas que surjan en el camino. + +Todos los cambios realizados por Cline se registran en la línea de tiempo de su archivo, proporcionando una forma sencilla de rastrear cambios y deshacerlos si es necesario. + + + +
+ + + +### Usar el navegador + +Con la nueva [habilidad de uso de computadora](https://www.anthropic.com/news/3-5-models-and-computer-use) de Claude 3.5 Sonnet, Cline puede iniciar un navegador, hacer clic en elementos, escribir texto y desplazarse, capturando capturas de pantalla y registros de consola. Esto permite la depuración interactiva, pruebas de extremo a extremo e incluso el uso general de la web. Esto le da la autonomía para solucionar errores visuales y problemas de tiempo de ejecución sin que tenga que copiar y pegar registros de errores. + +Intente pedirle a Cline que "pruebe la aplicación" y observe cómo ejecuta un comando como `npm run dev`, inicia su servidor de desarrollo local en un navegador y realiza una serie de pruebas para confirmar que todo funciona. [Vea una demostración aquí.](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### "agregar una herramienta que..." + +Gracias al [Model Context Protocol](https://github.com/modelcontextprotocol), Cline puede expandir sus habilidades mediante herramientas personalizadas. Mientras que puede usar [servidores creados por la comunidad](https://github.com/modelcontextprotocol/servers), Cline puede en su lugar crear e instalar herramientas adaptadas a su flujo de trabajo específico. Simplemente pida a Cline que "agregue una herramienta" y él se encargará de todo, desde la creación de un nuevo servidor MCP hasta la instalación en la extensión. Estas herramientas personalizadas se convierten en parte del conjunto de herramientas de Cline y están listas para ser utilizadas en tareas futuras. + +- "agregar una herramienta que recupere tickets de Jira": Recuperar ACs de tickets y poner a Cline a trabajar +- "agregar una herramienta que gestione AWS EC2s": Verificar métricas del servidor y escalar instancias hacia arriba o hacia abajo +- "agregar una herramienta que recupere los últimos incidentes de PagerDuty": Recuperar detalles y pedir a Cline que solucione errores + + + +
+ + + +### Agregar contexto + +**`@url`:** Inserte una URL para que la extensión la recupere y convierta en Markdown, útil cuando desee proporcionar a Cline los documentos más recientes + +**`@problems`:** Agregue errores y advertencias del espacio de trabajo (panel 'Problemas') que Cline debe solucionar + +**`@file`:** Agregue el contenido de un archivo para que no tenga que desperdiciar solicitudes de API para aprobar la lectura del archivo (+ para buscar archivos) + +**`@folder`:** Agregue los archivos de una carpeta a la vez para acelerar aún más su flujo de trabajo + + + +
+ + + +### Puntos de control: Comparar y Restaurar + +Mientras Cline trabaja en una tarea, la extensión crea una instantánea de su espacio de trabajo en cada paso. Puede usar el botón 'Comparar' para ver una diferencia entre la instantánea y su espacio de trabajo actual, y el botón 'Restaurar' para volver a ese punto. + +Por ejemplo, si está trabajando con un servidor web local, puede usar 'Restaurar solo espacio de trabajo' para probar rápidamente diferentes versiones de su aplicación, y luego 'Restaurar tarea y espacio de trabajo' cuando encuentre la versión desde la que desea continuar trabajando. Esto le permite explorar diferentes enfoques de manera segura sin perder progreso. + + + +
+ +## Contribuir + +Para contribuir al proyecto, comience con nuestra [guía de contribución](CONTRIBUTING.md) para aprender los conceptos básicos. También puede unirse a nuestro [Discord](https://discord.gg/cline) para chatear con otros colaboradores en el canal `#contributors`. Si está buscando un trabajo a tiempo completo, consulte nuestras vacantes en nuestra [página de carreras](https://cline.bot/join-us). + +
+Instrucciones de desarrollo local + +1. Clone el repositorio _(Requiere [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. Abra el proyecto en VSCode: + ```bash + code cline + ``` +3. Instale las dependencias necesarias para la extensión y la GUI de Webview: + ```bash + npm run install:all + ``` +4. Inicie presionando `F5` (o `Run`->`Start Debugging`) para abrir una nueva ventana de VSCode con la extensión cargada. (Es posible que deba instalar la [extensión de emparejadores de problemas de esbuild](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) si encuentra problemas al compilar el proyecto.) + +
+ +## Licencia + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) diff --git a/locales/ja/CODE_OF_CONDUCT.md b/locales/ja/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..a2c673a94d --- /dev/null +++ b/locales/ja/CODE_OF_CONDUCT.md @@ -0,0 +1,47 @@ +# コントリビューター規約行動規範 + +## 我々の誓い + +オープンで歓迎される環境を育むために、我々はコントリビューターおよびメンテナーとして、年齢、体型、障害、民族、性の特徴、性別のアイデンティティおよび表現、経験のレベル、教育、社会経済的地位、国籍、個人の外見、人種、宗教、または性的アイデンティティおよび指向に関係なく、プロジェクトおよびコミュニティへの参加がハラスメントのない体験となるよう誓います。 + +## 我々の基準 + +ポジティブな環境を作り出す行動の例としては、以下のものがあります: + +- 歓迎的で包括的な言葉を使うこと +- 異なる視点や経験を尊重すること +- 建設的な批判を優雅に受け入れること +- コミュニティのために最善を尽くすことに集中すること +- 他のコミュニティメンバーに対して共感を示すこと + +参加者による許容できない行動の例としては、以下のものがあります: + +- 性的な言葉や画像の使用、望まれない性的関心やアプローチ +- 荒らし、侮辱的/軽蔑的なコメント、個人的または政治的な攻撃 +- 公的または私的なハラスメント +- 明示的な許可なしに他人の個人情報(物理的または電子的な住所など)を公開すること +- プロフェッショナルな環境で不適切と合理的に見なされるその他の行動 + +## 我々の責任 + +プロジェクトのメンテナーは、許容される行動の基準を明確にする責任があり、不適切な行動の事例に対して適切かつ公平な是正措置を講じることが期待されています。 + +プロジェクトのメンテナーは、この行動規範に沿わないコメント、コミット、コード、ウィキの編集、問題、およびその他の貢献を削除、編集、または拒否する権利と責任を持ち、また、不適切、脅迫的、攻撃的、または有害と見なされるその他の行動を行ったコントリビューターを一時的または永久に禁止する権利と責任を持ちます。 + +## 範囲 + +この行動規範は、プロジェクトスペース内およびプロジェクトやコミュニティを代表する個人が公の場で行動する場合に適用されます。プロジェクトやコミュニティを代表する例としては、公式のプロジェクトメールアドレスを使用すること、公式のソーシャルメディアアカウントを通じて投稿すること、またはオンラインまたはオフラインのイベントで任命された代表として行動することが含まれます。プロジェクトの代表としての行動は、プロジェクトのメンテナーによってさらに定義および明確化される場合があります。 + +## 執行 + +虐待的、嫌がらせ、またはその他の許容できない行動の事例は、プロジェクトチームに hi@cline.bot まで報告することができます。すべての苦情はレビューおよび調査され、状況に応じて必要かつ適切な対応が行われます。プロジェクトチームは、事件の報告者に関する機密性を保持する義務があります。具体的な執行ポリシーの詳細は別途掲載される場合があります。 + +行動規範を誠実に遵守または執行しないプロジェクトのメンテナーは、プロジェクトのリーダーシップの他のメンバーによって一時的または永久的な影響を受ける可能性があります。 + +## 帰属 + +この行動規範は、[Contributor Covenant][homepage] バージョン 1.4 から適応されており、https://www.contributor-covenant.org/version/1/4/code-of-conduct.html で入手できます。 + +[homepage]: https://www.contributor-covenant.org + +この行動規範に関する一般的な質問への回答については、https://www.contributor-covenant.org/faq を参照してください。 diff --git a/locales/ja/CONTRIBUTING.md b/locales/ja/CONTRIBUTING.md new file mode 100644 index 0000000000..62544e27cb --- /dev/null +++ b/locales/ja/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Clineへの貢献 + +Clineへの貢献に興味をお持ちいただきありがとうございます。 + +## バグや問題の報告 + +バグ報告は、Clineを皆さんにとってより良いものにするために役立ちます!新しい問題を作成する前に、重複を避けるために[既存の問題を検索](https://github.com/cline/cline/issues)してください。バグを報告する準備ができたら、[問題ページ](https://github.com/cline/cline/issues/new/choose)に移動し、関連情報を記入するためのテンプレートをご利用ください。 + +
+ 🔐 重要: セキュリティ脆弱性を発見した場合は、Githubセキュリティツールを使用して非公開で報告してください。 +
+ +## 作業内容の決定 + +最初の貢献をお探しですか?["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue)や["help wanted"](https://github.com/cline/cline/labels/help%20wanted)のラベルが付いた問題をチェックしてください。これらは新しい貢献者向けに特に選ばれたもので、私たちが助けを求めている分野です! + +また、[ドキュメント](https://github.com/cline/cline/tree/main/docs)への貢献も歓迎します!誤字の修正、既存のガイドの改善、新しい教育コンテンツの作成など、コミュニティ主導のリソースリポジトリを構築するために皆さんの力をお借りしたいと考えています。`/docs`に飛び込んで、改善が必要な箇所を探してみてください。 + +大きな機能に取り組む予定がある場合は、まず[機能リクエスト](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop)を作成し、それがClineのビジョンに合致するかどうかを議論しましょう。 + +## 開発環境のセットアップ + +1. **VS Code拡張機能** + + - プロジェクトを開くと、VS Codeは推奨される拡張機能のインストールを促します + - これらの拡張機能は開発に必要です - すべてのインストールプロンプトを受け入れてください + - プロンプトを閉じた場合は、拡張機能パネルから手動でインストールできます + +2. **ローカル開発** + - `npm run install:all`を実行して依存関係をインストールします + - `npm run test`を実行してローカルでテストを実行します + - PRを提出する前に、`npm run format:fix`を実行してコードをフォーマットします + +## コードの作成と提出 + +誰でもClineにコードを貢献できますが、貢献がスムーズに統合されるように以下のガイドラインに従ってください: + +1. **プルリクエストを集中させる** + + - PRは単一の機能またはバグ修正に限定してください + - 大きな変更は小さな関連PRに分割してください + - 論理的なコミットに分けて、独立してレビューできるようにしてください + +2. **コード品質** + + - `npm run lint`を実行してコードスタイルをチェックします + - `npm run format`を実行してコードを自動的にフォーマットします + - すべてのPRは、リンティングとフォーマットを含むCIチェックに合格する必要があります + - 提出前にESLintの警告やエラーをすべて解決してください + - TypeScriptのベストプラクティスに従い、型の安全性を維持してください + +3. **テスト** + + - 新しい機能にはテストを追加してください + - `npm test`を実行してすべてのテストが合格することを確認してください + - 変更が既存のテストに影響を与える場合は、それらを更新してください + - 適切な場合には、ユニットテストと統合テストの両方を含めてください + +4. **コミットガイドライン** + + - 明確で説明的なコミットメッセージを書いてください + - 従来のコミット形式(例:"feat:", "fix:", "docs:")を使用してください + - コミットで関連する問題を#issue-numberを使用して参照してください + +5. **提出前に** + + - 最新のmainにブランチをリベースしてください + - ブランチが正常にビルドされることを確認してください + - すべてのテストが合格していることを再確認してください + - デバッグコードやコンソールログがないか変更を確認してください + +6. **プルリクエストの説明** + - 変更内容を明確に説明してください + - 変更をテストする手順を含めてください + - 破壊的な変更がある場合はリストしてください + - UIの変更にはスクリーンショットを追加してください + +## 貢献契約 + +プルリクエストを提出することで、あなたの貢献がプロジェクトと同じライセンス([Apache 2.0](LICENSE))の下でライセンスされることに同意したことになります。 + +覚えておいてください:Clineへの貢献はコードを書くことだけではなく、AI支援開発の未来を形作るコミュニティの一員になることです。一緒に素晴らしいものを作りましょう!🚀 diff --git a/locales/ja/README.md b/locales/ja/README.md new file mode 100644 index 0000000000..399b3a9a98 --- /dev/null +++ b/locales/ja/README.md @@ -0,0 +1,161 @@ +# Cline – OpenRouterでのナンバーワン + +

+ +

+ + + +Clineは、**CLI**と**エディター**を使用できるAIアシスタントです。 + +[Claude 3.5 Sonnetのエージェント的コーディング機能](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf)のおかげで、Clineは複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成と編集、大規模プロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可後)などのツールを使用して、コード補完や技術サポートを超えた支援を提供します。Clineは、Model Context Protocol (MCP)を使用して新しいツールを作成し、自身の機能を拡張することもできます。自律的なAIスクリプトは通常サンドボックス環境で実行されますが、この拡張機能はファイル変更やターミナルコマンドを承認するための人間インターフェースを提供し、エージェント的AIの可能性を安全かつアクセスしやすい方法で探求できます。 + +1. タスクを入力し、モックアップを機能するアプリに変換したり、スクリーンショットでバグを修正したりします。 +2. Clineは、ファイル構造とソースコードASTの分析、正規表現検索の実行、関連ファイルの読み取りから始め、既存プロジェクトに精通します。コンテキストに追加される情報を慎重に管理することで、大規模で複雑なプロジェクトでもコンテキストウィンドウを圧倒することなく貴重な支援を提供できます。 +3. Clineが必要な情報を取得すると、次のことができます: + - ファイルの作成と編集 + リンター/コンパイラーエラーの監視を行い、欠落したインポートや構文エラーなどの問題を自動的に修正します。 + - ターミナルでコマンドを直接実行し、作業中に出力を監視します。これにより、ファイル編集後の開発サーバーの問題に対応できます。 + - ウェブ開発タスクでは、ヘッドレスブラウザでサイトを起動し、クリック、入力、スクロール、スクリーンショットとコンソールログのキャプチャを行い、ランタイムエラーや視覚的なバグを修正します。 +4. タスクが完了すると、Clineは`open -a "Google Chrome" index.html`のようなターミナルコマンドを提示し、ボタンをクリックして実行できます。 + +> [!TIP] +> `CMD/CTRL + Shift + P`ショートカットを使用してコマンドパレットを開き、「Cline: Open In New Tab」と入力して、エディターのタブとして拡張機能を開きます。これにより、ファイルエクスプローラーと並行してClineを使用し、ワークスペースの変更をより明確に確認できます。 + +--- + + + +### どのAPIやモデルでも使用可能 + +Clineは、OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure、GCP VertexなどのAPIプロバイダーをサポートしています。また、OpenAI互換のAPIを設定したり、LM Studio/Ollamaを通じてローカルモデルを使用することもできます。OpenRouterを使用している場合、拡張機能は最新のモデルリストを取得し、最新のモデルをすぐに使用できるようにします。 + +拡張機能は、タスクループ全体と個々のリクエストのトークン総数とAPI使用コストを追跡し、各ステップで支出を把握できます。 + + + +
+ + + +### ターミナルでコマンドを実行 + +VSCode v1.93の新しい[シェル統合アップデート](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api)のおかげで、Clineはターミナルでコマンドを直接実行し、出力を受け取ることができます。これにより、パッケージのインストールやビルドスクリプトの実行からアプリケーションのデプロイ、データベースの管理、テストの実行まで、幅広いタスクを実行できます。Clineは、開発環境とツールチェーンに適応して、タスクを正確に実行します。 + +開発サーバーのような長時間実行されるプロセスの場合、「実行中に続行」ボタンを使用して、コマンドがバックグラウンドで実行されている間にClineがタスクを続行できるようにします。Clineが作業を進める中で、新しいターミナル出力が通知され、ファイル編集時のコンパイルエラーなどの問題に対応できます。 + + + +
+ + + +### ファイルの作成と編集 + +Clineはエディター内でファイルを作成および編集し、変更の差分ビューを提示します。差分ビューエディターでClineの変更を直接編集または元に戻すことができ、チャットでフィードバックを提供して満足するまで調整できます。Clineはリンター/コンパイラーエラー(欠落したインポート、構文エラーなど)も監視し、発生した問題を自動的に修正します。 + +Clineによるすべての変更はファイルのタイムラインに記録され、必要に応じて変更を追跡および元に戻す簡単な方法を提供します。 + + + +
+ + + +### ブラウザの使用 + +Claude 3.5 Sonnetの新しい[コンピュータ使用](https://www.anthropic.com/news/3-5-models-and-computer-use)機能により、Clineはブラウザを起動し、要素をクリック、テキストを入力、スクロールし、各ステップでスクリーンショットとコンソールログをキャプチャできます。これにより、インタラクティブなデバッグ、エンドツーエンドテスト、さらには一般的なウェブ使用が可能になります。これにより、エラーログを手動でコピー&ペーストすることなく、視覚的なバグやランタイムの問題を自律的に修正できます。 + +Clineに「アプリをテストして」と頼んでみてください。彼は`npm run dev`のようなコマンドを実行し、ローカルで実行中の開発サーバーをブラウザで起動し、一連のテストを実行してすべてが正常に動作することを確認します。[デモはこちら。](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### 「ツールを追加して...」 + +[Model Context Protocol](https://github.com/modelcontextprotocol)のおかげで、Clineはカスタムツールを通じて機能を拡張できます。[コミュニティ製サーバー](https://github.com/modelcontextprotocol/servers)を使用することもできますが、Clineは代わりに特定のワークフローに合わせたツールを作成してインストールできます。「ツールを追加して」と頼むだけで、Clineは新しいMCPサーバーの作成から拡張機能へのインストールまでをすべて処理します。これらのカスタムツールはClineのツールキットの一部となり、将来のタスクで使用できるようになります。 + +- 「Jiraチケットを取得するツールを追加して」:チケットACを取得し、Clineに作業を依頼 +- 「AWS EC2を管理するツールを追加して」:サーバーメトリクスを確認し、インスタンスをスケールアップまたはダウン +- 「最新のPagerDutyインシデントを取得するツールを追加して」:詳細を取得し、Clineにバグ修正を依頼 + + + +
+ + + +### コンテキストを追加 + +**`@url`:** 最新のドキュメントをClineに提供したい場合に、URLを貼り付けて拡張機能が取得し、Markdownに変換します。 + +**`@problems`:** Clineが修正するためのワークスペースエラーと警告(「問題」パネル)を追加します。 + +**`@file`:** ファイルの内容を追加し、読み取りファイルを承認するAPIリクエストを節約します(+ファイルを検索して入力)。 + +**`@folder`:** フォルダーのファイルを一度に追加して、ワークフローをさらにスピードアップします。 + + + +
+ + + +### チェックポイント:比較と復元 + +Clineがタスクを進める中で、拡張機能は各ステップでワークスペースのスナップショットを撮ります。「比較」ボタンを使用してスナップショットと現在のワークスペースの差分を確認し、「復元」ボタンを使用してそのポイントにロールバックできます。 + +たとえば、ローカルウェブサーバーで作業している場合、「ワークスペースのみを復元」を使用して異なるバージョンのアプリを迅速にテストし、「タスクとワークスペースを復元」を使用して続行したいバージョンを見つけたときに使用します。これにより、進行状況を失うことなく異なるアプローチを安全に探求できます。 + + + +
+ +## 貢献 + +プロジェクトに貢献するには、[貢献ガイド](CONTRIBUTING.md)から基本を学び始めてください。また、[Discord](https://discord.gg/cline)に参加して、`#contributors`チャンネルで他の貢献者とチャットすることもできます。フルタイムの仕事を探している場合は、[採用ページ](https://cline.bot/join-us)でオープンポジションを確認してください。 + +
+ローカル開発の手順 + +1. リポジトリをクローンします _(Requires [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. プロジェクトをVSCodeで開きます: + ```bash + code cline + ``` +3. 拡張機能とwebview-guiの必要な依存関係をインストールします: + ```bash + npm run install:all + ``` +4. `F5`を押して(または`Run`->`Start Debugging`)、拡張機能が読み込まれた新しいVSCodeウィンドウを開きます。(プロジェクトのビルドに問題がある場合は、[esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers)をインストールする必要があるかもしれません。) + +
+ +## ライセンス + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) diff --git a/locales/zh-cn/CODE_OF_CONDUCT.md b/locales/zh-cn/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..41229538e1 --- /dev/null +++ b/locales/zh-cn/CODE_OF_CONDUCT.md @@ -0,0 +1,47 @@ +# 贡献者公约行为准则 + +## 我们的承诺 + +为了营造一个开放和欢迎的环境,我们作为贡献者和维护者承诺让我们的项目和社区的参与体验对每个人都无骚扰,无论年龄、体型、残疾、种族、性别特征、性别认同和表达、经验水平、教育程度、社会经济地位、国籍、个人外貌、种族、宗教或性取向。 + +## 我们的标准 + +有助于创造积极环境的行为示例包括: + +- 使用欢迎和包容的语言 +- 尊重不同的观点和经验 +- 优雅地接受建设性的批评 +- 专注于对社区最有利的事情 +- 对其他社区成员表现出同理心 + +参与者不可接受的行为示例包括: + +- 使用性化语言或图像以及不受欢迎的性关注或挑逗 +- 故意挑衅、侮辱/贬低性评论和个人或政治攻击 +- 公开或私下骚扰 +- 未经明确许可发布他人的私人信息,如物理或电子地址 +- 其他在专业环境中合理认为不适当的行为 + +## 我们的责任 + +项目维护者有责任澄清可接受行为的标准,并期望对任何不可接受行为采取适当和公平的纠正措施。 + +项目维护者有权利和责任删除、编辑或拒绝与本行为准则不一致的评论、提交、代码、维基编辑、问题和其他贡献,或暂时或永久禁止任何贡献者进行他们认为不适当、威胁、冒犯或有害的其他行为。 + +## 适用范围 + +本行为准则适用于项目空间内和公共空间中代表项目或其社区的个人。代表项目或社区的示例包括使用官方项目电子邮件地址,通过官方社交媒体账户发布,或在在线或离线活动中作为指定代表。项目的代表性可能由项目维护者进一步定义和澄清。 + +## 执行 + +滥用、骚扰或其他不可接受行为的实例可以通过联系项目团队 hi@cline.bot 报告。所有投诉将被审查和调查,并将导致根据情况认为必要和适当的回应。项目团队有义务对事件报告者保密。具体执行政策的详细信息可能会单独发布。 + +未能善意遵守或执行行为准则的项目维护者可能会面临由项目领导的其他成员决定的临时或永久后果。 + +## 归属 + +本行为准则改编自 [贡献者公约][主页],版本 1.4,可在 https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 获取。 + +[主页]: https://www.contributor-covenant.org + +有关此行为准则的常见问题的答案,请参见 https://www.contributor-covenant.org/faq diff --git a/locales/zh-cn/CONTRIBUTING.md b/locales/zh-cn/CONTRIBUTING.md new file mode 100644 index 0000000000..f528d7c33f --- /dev/null +++ b/locales/zh-cn/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# 贡献到 Cline + +我们很高兴您有兴趣为 Cline 做出贡献。无论您是修复错误、添加功能还是改进我们的文档,每一份贡献都让 Cline 更加智能!为了保持我们的社区充满活力和欢迎,所有成员必须遵守我们的[行为准则](CODE_OF_CONDUCT.md)。 + +## 报告错误或问题 + +错误报告有助于让 Cline 对每个人都更好!在创建新问题之前,请先[搜索现有问题](https://github.com/cline/cline/issues)以避免重复。当您准备好报告错误时,请前往我们的[问题页面](https://github.com/cline/cline/issues/new/choose),在那里您会找到一个模板来帮助您填写相关信息。 + +
+ 🔐 重要:如果您发现安全漏洞,请使用Github 安全工具私下报告。 +
+ +## 决定要做什么 + +寻找一个好的首次贡献?查看标记为["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue)或["help wanted"](https://github.com/cline/cline/labels/help%20wanted)的问题。这些是专门为新贡献者策划的领域,我们非常欢迎您的帮助! + +我们也欢迎对我们的[文档](https://github.com/cline/cline/tree/main/docs)做出贡献!无论是修正错别字、改进现有指南,还是创建新的教育内容 - 我们希望建立一个社区驱动的资源库,帮助每个人充分利用 Cline。您可以从深入研究 `/docs` 并寻找需要改进的地方开始。 + +如果您计划开发一个更大的功能,请先创建一个[功能请求](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop),以便我们讨论它是否符合 Cline 的愿景。 + +## 开发设置 + +1. **VS Code 扩展** + + - 打开项目时,VS Code 会提示您安装推荐的扩展 + - 这些扩展是开发所必需的 - 请接受所有安装提示 + - 如果您忽略了提示,可以从扩展面板手动安装它们 + +2. **本地开发** + - 运行 `npm run install:all` 安装依赖项 + - 运行 `npm run test` 本地运行测试 + - 提交 PR 之前,运行 `npm run format:fix` 格式化您的代码 + +## 编写和提交代码 + +任何人都可以为 Cline 贡献代码,但我们要求您遵循以下指南,以确保您的贡献能够顺利集成: + +1. **保持 Pull Request 集中** + + - 将 PR 限制为单个功能或错误修复 + - 将较大的更改拆分为较小的相关 PR + - 将更改分为逻辑提交,以便独立审查 + +2. **代码质量** + + - 运行 `npm run lint` 检查代码风格 + - 运行 `npm run format` 自动格式化代码 + - 所有 PR 必须通过 CI 检查,包括 lint 和格式化 + - 提交前解决所有 ESLint 警告或错误 + - 遵循 TypeScript 最佳实践并保持类型安全 + +3. **测试** + + - 为新功能添加测试 + - 运行 `npm test` 确保所有测试通过 + - 如果您的更改影响现有测试,请更新它们 + - 在适当的情况下包括单元测试和集成测试 + +4. **提交指南** + + - 编写清晰、描述性的提交消息 + - 使用常规提交格式(例如,“feat:”,“fix:”,“docs:”) + - 在提交中引用相关问题,使用 #issue-number + +5. **提交前** + + - 将您的分支重新基于最新的 main + - 确保您的分支成功构建 + - 仔细检查所有测试是否通过 + - 检查您的更改是否有任何调试代码或控制台日志 + +6. **Pull Request 描述** + - 清楚描述您的更改内容 + - 包括测试更改的步骤 + - 列出任何重大更改 + - 对于 UI 更改,添加截图 + +## 贡献协议 + +通过提交 pull request,您同意您的贡献将根据与项目相同的许可证([Apache 2.0](LICENSE))进行许可。 + +记住:为 Cline 做贡献不仅仅是编写代码 - 这是成为一个社区的一部分,共同塑造 AI 辅助开发的未来。让我们一起构建一些令人惊叹的东西!🚀 diff --git a/locales/zh-cn/README.md b/locales/zh-cn/README.md new file mode 100644 index 0000000000..0e6fd20d50 --- /dev/null +++ b/locales/zh-cn/README.md @@ -0,0 +1,162 @@ +# Cline – OpenRouter 排名第一 + +

+ +

+ + + +认识 Cline,一个可以使用你的 **CLI** 和 **编辑器** 的 AI 助手。 + +感谢 [Claude 3.5 Sonnet 的代理编码能力](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf),Cline 可以一步步处理复杂的软件开发任务。通过允许他创建和编辑文件、探索大型项目、使用浏览器和执行终端命令(在你授予权限后),他可以提供超越代码完成或技术支持的帮助。Cline 甚至可以使用 Model Context Protocol (MCP) 创建新工具并扩展自己的能力。虽然自主 AI 脚本传统上在沙盒环境中运行,但此扩展提供了一个人机交互的 GUI 来批准每个文件更改和终端命令,提供了一种安全且可访问的方式来探索代理 AI 的潜力。 + +1. 输入你的任务并添加图像,将模型转换为功能应用程序或通过截图修复错误。 +2. Cline 首先分析你的文件结构和源代码 AST,运行正则表达式搜索,并阅读相关文件以了解现有项目。通过仔细管理添加到上下文中的信息,Cline 即使在大型复杂项目中也能提供有价值的帮助,而不会使上下文窗口过载。 +3. 一旦 Cline 获得所需信息,他可以: + - 创建和编辑文件 + 监控 linter/编译器错误,从而主动修复诸如缺少导入和语法错误等问题。 + - 直接在你的终端中执行命令并监控其输出,从而在编辑文件后对开发服务器问题做出反应。 + - 对于 Web 开发任务,Cline 可以在无头浏览器中启动网站,点击、输入、滚动并捕获截图和控制台日志,从而修复运行时错误和视觉错误。 +4. 当任务完成时,Cline 将通过终端命令如 `open -a "Google Chrome" index.html` 向你展示结果,你可以通过点击按钮运行该命令。 + +> [!提示] +> 使用 `CMD/CTRL + Shift + P` 快捷键打开命令面板并输入 "Cline: Open In New Tab" 将扩展作为标签在编辑器中打开。这让你可以与文件资源管理器并排使用 Cline,更清楚地看到他如何改变你的工作空间。 + +--- + + + +### 使用任何 API 和模型 + +Cline 支持 OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure 和 GCP Vertex 等 API 提供商。你还可以配置任何兼容 OpenAI 的 API,或通过 LM Studio/Ollama 使用本地模型。如果你使用 OpenRouter,扩展会获取他们的最新模型列表,让你在新模型可用时立即使用。 + +扩展还会跟踪整个任务循环和单个请求的总令牌和 API 使用成本,让你在每一步都了解支出情况。 + + + +
+ + + +### 在终端中运行命令 + +感谢 VSCode v1.93 中的新 [终端 shell 集成更新](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api),Cline 可以直接在你的终端中执行命令并接收输出。这使他能够执行广泛的任务,从安装包和运行构建脚本到部署应用程序、管理数据库和执行测试,同时适应你的开发环境和工具链以正确完成工作。 + +对于长时间运行的进程如开发服务器,使用“在运行时继续”按钮让 Cline 在命令后台运行时继续任务。当 Cline 工作时,他会在过程中收到任何新的终端输出通知,让他对可能出现的问题做出反应,例如编辑文件时的编译时错误。 + + + +
+ + + +### 创建和编辑文件 + +Cline 可以直接在你的编辑器中创建和编辑文件,向你展示更改的差异视图。你可以直接在差异视图编辑器中编辑或恢复 Cline 的更改,或在聊天中提供反馈,直到你对结果满意。Cline 还会监控 linter/编译器错误(缺少导入、语法错误等),以便他在过程中自行修复出现的问题。 + +Cline 所做的所有更改都会记录在你的文件时间轴中,提供了一种简单的方法来跟踪和恢复修改(如果需要)。 + + + +
+ + + +### 使用浏览器 + +借助 Claude 3.5 Sonnet 的新 [计算机使用](https://www.anthropic.com/news/3-5-models-and-computer-use) 功能,Cline 可以启动浏览器,点击元素,输入文本和滚动,在每一步捕获截图和控制台日志。这允许进行交互式调试、端到端测试,甚至是一般的网页使用!这使他能够自主修复视觉错误和运行时问题,而无需你亲自操作和复制粘贴错误日志。 + +试试让 Cline “测试应用程序”,看看他如何运行 `npm run dev` 命令,在浏览器中启动你本地运行的开发服务器,并执行一系列测试以确认一切正常。[在这里查看演示。](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### “添加一个工具……” + +感谢 [Model Context Protocol](https://github.com/modelcontextprotocol),Cline 可以通过自定义工具扩展他的能力。虽然你可以使用 [社区制作的服务器](https://github.com/modelcontextprotocol/servers),但 Cline 可以创建和安装适合你特定工作流程的工具。只需让 Cline “添加一个工具”,他将处理所有事情,从创建新的 MCP 服务器到将其安装到扩展中。这些自定义工具将成为 Cline 工具包的一部分,准备在未来的任务中使用。 + +- “添加一个获取 Jira 工单的工具”:检索工单 AC 并让 Cline 开始工作 +- “添加一个管理 AWS EC2 的工具”:检查服务器指标并上下扩展实例 +- “添加一个获取最新 PagerDuty 事件的工具”:获取详细信息并让 Cline 修复错误 + + + +
+ + + +### 添加上下文 + +**`@url`:** 粘贴一个 URL 以供扩展获取并转换为 markdown,当你想给 Cline 提供最新文档时非常有用 + +**`@problems`:** 添加工作区错误和警告(“问题”面板)以供 Cline 修复 + +**`@file`:** 添加文件内容,这样你就不必浪费 API 请求批准读取文件(+ 输入以搜索文件) + +**`@folder`:** 一次添加文件夹的文件,以进一步加快你的工作流程 + + + +
+ + + +### 检查点:比较和恢复 + +当 Cline 完成任务时,扩展会在每一步拍摄你的工作区快照。你可以使用“比较”按钮查看快照和当前工作区之间的差异,并使用“恢复”按钮回滚到该点。 + +例如,当使用本地 Web 服务器时,你可以使用“仅恢复工作区”快速测试应用程序的不同版本,然后在找到要继续构建的版本时使用“恢复任务和工作区”。这让你可以安全地探索不同的方法而不会丢失进度。 + + + +
+ +## 贡献 + +要为项目做出贡献,请从我们的 [贡献指南](CONTRIBUTING.md) 开始,了解基础知识。你还可以加入我们的 [Discord](https://discord.gg/cline) 在 `#contributors` 频道与其他贡献者聊天。如果你正在寻找全职工作,请查看我们在 [招聘页面](https://cline.bot/join-us) 上的开放职位! + +
+本地开发说明 + +1. 克隆仓库 _(需要 [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. 在 VSCode 中打开项目: + ```bash + code cline + ``` +3. 安装扩展和 webview-gui 的必要依赖: + ```bash + npm run install:all + ``` +4. 按 `F5`(或 `运行`->`开始调试`)启动以打开一个加载了扩展的新 VSCode 窗口。(如果你在构建项目时遇到问题,可能需要安装 [esbuild problem matchers 扩展](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers)) + +
+ +## 许可证 + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) + diff --git a/locales/zh-tw/CODE_OF_CONDUCT.md b/locales/zh-tw/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..9f8791ecd9 --- /dev/null +++ b/locales/zh-tw/CODE_OF_CONDUCT.md @@ -0,0 +1,47 @@ +# 貢獻者公約行為準則 + +## 我們的承諾 + +為了促進一個開放和歡迎的環境,我們作為貢獻者和維護者承諾,使我們的項目和社區的參與對每個人來說都是一個無騷擾的體驗,不論年齡、體型、殘疾、種族、性別特徵、性別認同和表達、經驗水平、教育程度、社會經濟地位、國籍、個人外貌、種族、宗教或性取向。 + +## 我們的標準 + +有助於創造積極環境的行為示例包括: + +- 使用歡迎和包容的語言 +- 尊重不同的觀點和經驗 +- 優雅地接受建設性的批評 +- 專注於對社區最有利的事情 +- 對其他社區成員表示同情 + +參與者不可接受的行為示例包括: + +- 使用性化語言或圖像以及不受歡迎的性注意或挑逗 +- 騷擾、侮辱/貶低性評論和個人或政治攻擊 +- 公開或私下騷擾 +- 未經明確許可發布他人的私人信息,例如物理或電子地址 +- 其他在專業環境中合理認為不適當的行為 + +## 我們的責任 + +項目維護者有責任澄清可接受行為的標準,並預期對任何不可接受行為的實例採取適當和公平的糾正行動。 + +項目維護者有權利和責任刪除、編輯或拒絕與本行為準則不符的評論、提交、代碼、維基編輯、問題和其他貢獻,或暫時或永久禁止任何他們認為不適當、威脅、冒犯或有害的貢獻者。 + +## 範圍 + +此行為準則適用於項目空間內以及當個人代表項目或其社區時的公共空間。代表項目或社區的示例包括使用官方項目電子郵件地址、通過官方社交媒體帳戶發布或作為在線或離線活動的指定代表。項目的代表可能由項目維護者進一步定義和澄清。 + +## 執行 + +濫用、騷擾或其他不可接受行為的實例可以通過聯繫項目團隊 hi@cline.bot 來報告。所有投訴將被審查和調查,並將根據情況作出必要和適當的回應。項目團隊有義務對事件的報告者保密。具體執行政策的詳細信息可能會單獨發布。 + +未能善意遵循或執行行為準則的項目維護者可能會面臨由項目領導層其他成員決定的暫時或永久後果。 + +## 歸屬 + +此行為準則改編自 [Contributor Covenant][homepage],版本 1.4,可在 https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 獲得。 + +[homepage]: https://www.contributor-covenant.org + +有關此行為準則的常見問題的答案,請參見 https://www.contributor-covenant.org/faq diff --git a/locales/zh-tw/CONTRIBUTING.md b/locales/zh-tw/CONTRIBUTING.md new file mode 100644 index 0000000000..698a897c50 --- /dev/null +++ b/locales/zh-tw/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# 貢獻於 Cline + +我們很高興您有興趣為 Cline 做出貢獻。無論您是修復錯誤、添加功能還是改進我們的文檔,每一個貢獻都讓 Cline 更加智能!為了保持我們的社區充滿活力和歡迎,所有成員必須遵守我們的[行為準則](CODE_OF_CONDUCT.md)。 + +## 報告錯誤或問題 + +錯誤報告有助於讓 Cline 對每個人都更好!在創建新問題之前,請[搜索現有問題](https://github.com/cline/cline/issues)以避免重複。當您準備報告錯誤時,請前往我們的[問題頁面](https://github.com/cline/cline/issues/new/choose),您會找到一個模板來幫助您填寫相關信息。 + +
+ 🔐 重要: 如果您發現安全漏洞,請使用Github 安全工具私下報告。 +
+ +## 決定要做什麼 + +尋找一個好的首次貢獻?查看標有["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue)或["help wanted"](https://github.com/cline/cline/labels/help%20wanted)的問題。這些是專門為新貢獻者和我們希望得到幫助的領域策劃的! + +我們也歡迎對我們[文檔](https://github.com/cline/cline/tree/main/docs)的貢獻!無論是修正錯別字、改進現有指南還是創建新的教育內容 - 我們希望建立一個由社區驅動的資源庫,幫助每個人充分利用 Cline。您可以從深入研究 `/docs` 並尋找需要改進的領域開始。 + +如果您計劃開發一個更大的功能,請先創建一個[功能請求](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop),以便我們討論它是否符合 Cline 的願景。 + +## 開發設置 + +1. **VS Code 擴展** + + - 打開項目時,VS Code 會提示您安裝推薦的擴展 + - 這些擴展是開發所需的 - 請接受所有安裝提示 + - 如果您忽略了提示,可以從擴展面板手動安裝它們 + +2. **本地開發** + - 運行 `npm run install:all` 安裝依賴項 + - 運行 `npm run test` 本地運行測試 + - 提交 PR 之前,運行 `npm run format:fix` 格式化您的代碼 + +## 編寫和提交代碼 + +任何人都可以為 Cline 貢獻代碼,但我們要求您遵循以下指南,以確保您的貢獻能夠順利集成: + +1. **保持 Pull Requests 集中** + + - 將 PR 限制在單個功能或錯誤修復 + - 將較大的更改拆分為較小的相關 PR + - 將更改分為邏輯提交,可以獨立審查 + +2. **代碼質量** + + - 運行 `npm run lint` 檢查代碼風格 + - 運行 `npm run format` 自動格式化代碼 + - 所有 PR 必須通過包括 lint 和格式化在內的 CI 檢查 + - 提交前解決所有 ESLint 警告或錯誤 + - 遵循 TypeScript 最佳實踐並保持類型安全 + +3. **測試** + + - 為新功能添加測試 + - 運行 `npm test` 確保所有測試通過 + - 如果您的更改影響現有測試,請更新它們 + - 在適當的地方包括單元測試和集成測試 + +4. **提交指南** + + - 撰寫清晰、描述性的提交消息 + - 使用常規提交格式(例如 "feat:"、"fix:"、"docs:") + - 在提交中引用相關問題,使用 #issue-number + +5. **提交前** + + - 將您的分支重新基於最新的 main + - 確保您的分支成功構建 + - 仔細檢查所有測試是否通過 + - 檢查您的更改是否有任何調試代碼或控制台日誌 + +6. **Pull Request 描述** + - 清楚地描述您的更改內容 + - 包括測試更改的步驟 + - 列出任何重大更改 + - 為 UI 更改添加截圖 + +## 貢獻協議 + +通過提交 pull request,您同意您的貢獻將根據與項目相同的許可證([Apache 2.0](LICENSE))進行許可。 + +記住:貢獻於 Cline 不僅僅是編寫代碼 - 這是關於成為一個塑造 AI 輔助開發未來的社區的一部分。讓我們一起創造一些驚人的東西!🚀 diff --git a/locales/zh-tw/README.md b/locales/zh-tw/README.md new file mode 100644 index 0000000000..0325650d01 --- /dev/null +++ b/locales/zh-tw/README.md @@ -0,0 +1,161 @@ +# Cline – OpenRouter 上的 \#1 + +

+ +

+ + + +認識 Cline,一個可以使用你的 **CLI** 和 **編輯器** 的 AI 助手。 + +感謝 [Claude 3.5 Sonnet 的代理編碼能力](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf),Cline 可以一步步處理複雜的軟件開發任務。通過允許他創建和編輯文件、探索大型項目、使用瀏覽器和執行終端命令(在你授予權限後),他可以提供超越代碼完成或技術支持的幫助。Cline 甚至可以使用 Model Context Protocol (MCP) 創建新工具並擴展自己的能力。雖然自主 AI 腳本傳統上在沙盒環境中運行,但此擴展提供了一個人機交互的 GUI 來批准每個文件更改和終端命令,提供了一種安全且可訪問的方式來探索代理 AI 的潛力。 + +1. 輸入你的任務並添加圖像,將模型轉換為功能應用程序或通過截圖修復錯誤。 +2. Cline 首先分析你的文件結構和源代碼 AST,運行正則表達式搜索,並閱讀相關文件以了解現有項目。通過仔細管理添加到上下文中的信息,Cline 即使在大型複雜項目中也能提供有價值的幫助,而不會使上下文窗口過載。 +3. 一旦 Cline 獲得所需信息,他可以: + - 創建和編輯文件 + 監控 linter/編譯器錯誤,從而主動修復諸如缺少導入和語法錯誤等問題。 + - 直接在你的終端中執行命令並監控其輸出,從而在編輯文件後對開發服務器問題做出反應。 + - 對於 Web 開發任務,Cline 可以在無頭瀏覽器中啟動網站,點擊、輸入、滾動並捕獲截圖和控制台日誌,從而修復運行時錯誤和視覺錯誤。 +4. 當任務完成時,Cline 將通過終端命令如 `open -a "Google Chrome" index.html` 向你展示結果,你可以通過點擊按鈕運行該命令。 + +> [!提示] +> 使用 `CMD/CTRL + Shift + P` 快捷鍵打開命令面板並輸入 "Cline: Open In New Tab" 將擴展作為標籤在編輯器中打開。這讓你可以與文件資源管理器並排使用 Cline,更清楚地看到他如何改變你的工作空間。 + +--- + + + +### 使用任何 API 和模型 + +Cline 支持 OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure 和 GCP Vertex 等 API 提供商。你還可以配置任何兼容 OpenAI 的 API,或通過 LM Studio/Ollama 使用本地模型。如果你使用 OpenRouter,擴展會獲取他們的最新模型列表,讓你在新模型可用時立即使用。 + +擴展還會跟蹤整個任務循環和單個請求的總令牌和 API 使用成本,讓你在每一步都了解支出情況。 + + + +
+ + + +### 在終端中運行命令 + +感謝 VSCode v1.93 中的新 [終端 shell 集成更新](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api),Cline 可以直接在你的終端中執行命令並接收輸出。這使他能夠執行廣泛的任務,從安裝包和運行構建腳本到部署應用程序、管理數據庫和執行測試,同時適應你的開發環境和工具鏈以正確完成工作。 + +對於長時間運行的進程如開發服務器,使用“在運行時繼續”按鈕讓 Cline 在命令後台運行時繼續任務。當 Cline 工作時,他會在過程中收到任何新的終端輸出通知,讓他對可能出現的問題做出反應,例如編輯文件時的編譯時錯誤。 + + + +
+ + + +### 創建和編輯文件 + +Cline 可以直接在你的編輯器中創建和編輯文件,向你展示更改的差異視圖。你可以直接在差異視圖編輯器中編輯或恢復 Cline 的更改,或在聊天中提供反饋,直到你對結果滿意。Cline 還會監控 linter/編譯器錯誤(缺少導入、語法錯誤等),以便他在過程中自行修復出現的問題。 + +Cline 所做的所有更改都會記錄在你的文件時間軸中,提供了一種簡單的方法來跟蹤和恢復修改(如果需要)。 + + + +
+ + + +### 使用瀏覽器 + +借助 Claude 3.5 Sonnet 的新 [計算機使用](https://www.anthropic.com/news/3-5-models-and-computer-use) 功能,Cline 可以啟動瀏覽器,點擊元素,輸入文本和滾動,在每一步捕獲截圖和控制台日誌。這允許進行交互式調試、端到端測試,甚至是一般的網頁使用!這使他能夠自主修復視覺錯誤和運行時問題,而無需你親自操作和複製粘貼錯誤日誌。 + +試試讓 Cline “測試應用程序”,看看他如何運行 `npm run dev` 命令,在瀏覽器中啟動你本地運行的開發服務器,並執行一系列測試以確認一切正常。[在這裡查看演示。](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### “添加一個工具……” + +感謝 [Model Context Protocol](https://github.com/modelcontextprotocol),Cline 可以通過自定義工具擴展他的能力。雖然你可以使用 [社區製作的服務器](https://github.com/modelcontextprotocol/servers),但 Cline 可以創建和安裝適合你特定工作流程的工具。只需讓 Cline “添加一個工具”,他將處理所有事情,從創建新的 MCP 服務器到將其安裝到擴展中。這些自定義工具將成為 Cline 工具包的一部分,準備在未來的任務中使用。 + +- “添加一個獲取 Jira 工單的工具”:檢索工單 AC 並讓 Cline 開始工作 +- “添加一個管理 AWS EC2 的工具”:檢查服務器指標並上下擴展實例 +- “添加一個獲取最新 PagerDuty 事件的工具”:獲取詳細信息並讓 Cline 修復錯誤 + + + +
+ + + +### 添加上下文 + +**`@url`:** 粘貼一個 URL 以供擴展獲取並轉換為 markdown,當你想給 Cline 提供最新文檔時非常有用 + +**`@problems`:** 添加工作區錯誤和警告(“問題”面板)以供 Cline 修復 + +**`@file`:** 添加文件內容,這樣你就不必浪費 API 請求批准讀取文件(+ 輸入以搜索文件) + +**`@folder`:** 一次添加文件夾的文件,以進一步加快你的工作流程 + + + +
+ + + +### 檢查點:比較和恢復 + +當 Cline 完成任務時,擴展會在每一步拍攝你的工作區快照。你可以使用“比較”按鈕查看快照和當前工作區之間的差異,並使用“恢復”按鈕回滾到該點。 + +例如,當使用本地 Web 服務器時,你可以使用“僅恢復工作區”快速測試應用程序的不同版本,然後在找到要繼續構建的版本時使用“恢復任務和工作區”。這讓你可以安全地探索不同的方法而不會丟失進度。 + + + +
+ +## 貢獻 + +要為項目做出貢獻,請從我們的 [貢獻指南](CONTRIBUTING.md) 開始,了解基礎知識。你還可以加入我們的 [Discord](https://discord.gg/cline) 在 `#contributors` 頻道與其他貢獻者聊天。如果你正在尋找全職工作,請查看我們在 [招聘頁面](https://cline.bot/join-us) 上的開放職位! + +
+本地開發說明 + +1. 克隆倉庫 _(需要 [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. 在 VSCode 中打開項目: + ```bash + code cline + ``` +3. 安裝擴展和 webview-gui 的必要依賴: + ```bash + npm run install:all + ``` +4. 按 `F5`(或 `運行`->`開始調試`)啟動以打開一個加載了擴展的新 VSCode 窗口。(如果你在構建項目時遇到問題,可能需要安裝 [esbuild problem matchers 擴展](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers)) + +
+ +## 許可證 + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) diff --git a/package-lock.json b/package-lock.json index a80a79fbe1..25b4a9e508 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,22 @@ { "name": "claude-dev", - "version": "3.0.4", + "version": "3.2.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.0.4", + "version": "3.2.12", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.26.0", "@anthropic-ai/vertex-sdk": "^0.4.1", "@google/generative-ai": "^0.18.0", + "@mistralai/mistralai": "^1.3.6", "@modelcontextprotocol/sdk": "^1.0.1", "@types/clone-deep": "^4.0.4", + "@types/get-folder-size": "^3.0.4", "@types/pdf-parse": "^1.1.4", "@types/turndown": "^5.0.5", "@vscode/codicons": "^0.0.36", @@ -27,17 +29,21 @@ "diff": "^5.2.0", "execa": "^9.5.2", "fast-deep-equal": "^3.1.3", + "firebase": "^11.2.0", + "get-folder-size": "^5.0.0", "globby": "^14.0.2", + "ignore": "^7.0.3", "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", "monaco-vscode-textmate-theme-converter": "^0.1.7", - "openai": "^4.61.0", + "openai": "^4.82.0", "os-name": "^6.0.0", "p-wait-for": "^5.0.2", "pdf-parse": "^1.1.1", "puppeteer-chromium-resolver": "^23.0.0", "puppeteer-core": "^23.4.0", "serialize-error": "^11.0.3", + "simple-git": "^3.27.0", "strip-ansi": "^7.1.0", "tree-sitter-wasms": "^0.1.11", "turndown": "^7.2.0", @@ -45,6 +51,8 @@ "zod": "^3.23.8" }, "devDependencies": { + "@changesets/cli": "^2.27.12", + "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", "@types/node": "20.x", @@ -54,8 +62,10 @@ "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", + "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -2168,6 +2178,19 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/@babel/runtime": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", + "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -2175,72 +2198,339 @@ "dev": true, "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@changesets/apply-release-plan": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.8.tgz", + "integrity": "sha512-qjMUj4DYQ1Z6qHawsn7S71SujrExJ+nceyKKyI9iB+M5p9lCL55afuEd6uLBPRpLGWQwkwvWegDHtwHJb1UjpA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@changesets/config": "^3.0.5", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], + "node_modules/@changesets/apply-release-plan/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "bin": { + "prettier": "bin-prettier.js" + }, "engines": { - "node": ">=12" + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], + "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.5.tgz", + "integrity": "sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", + "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.27.12", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.12.tgz", + "integrity": "sha512-9o3fOfHYOvBnyEn0mcahB7wzaA3P4bGJf8PNqGit5PKaMEFdsRixik+txkrJWd2VX+O6wRFXpxQL8j/1ANKE9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^7.0.8", + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/changelog-git": "^0.2.0", + "@changesets/config": "^3.0.5", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-release-plan": "^4.0.6", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@changesets/write": "^0.3.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "ci-info": "^3.7.0", + "enquirer": "^2.4.1", + "external-editor": "^3.1.0", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "p-limit": "^2.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=12" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@changesets/cli/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/config": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.5.tgz", + "integrity": "sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/logger": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz", + "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.6.tgz", + "integrity": "sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/config": "^3.0.5", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/git": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.2.tgz", + "integrity": "sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", + "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "js-yaml": "^3.13.1" + } + }, + "node_modules/@changesets/parse/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@changesets/parse/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz", + "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.2.tgz", + "integrity": "sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.0", + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz", + "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", + "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/write": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", + "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "prettier": "^2.7.1" + } + }, + "node_modules/@changesets/write/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/@esbuild/darwin-arm64": { @@ -2260,312 +2550,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2627,6 +2611,15 @@ "concat-map": "0.0.1" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2650,6 +2643,713 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@firebase/analytics": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.11.tgz", + "integrity": "sha512-zwuPiRE0+hgcS95JZbJ6DFQN4xYFO8IyGxpeePTV51YJMwCf3lkBa6FnZ/iXIqDKcBPMgMuuEZozI0BJWaLEYg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.17.tgz", + "integrity": "sha512-SJNVOeTvzdqZQvXFzj7yAirXnYcLDxh57wBFROfeowq/kRN1AqOw1tG6U4OiFOEhqi7s3xLze/LMkZatk2IEww==", + "dependencies": { + "@firebase/analytics": "0.10.11", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==" + }, + "node_modules/@firebase/analytics/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.18.tgz", + "integrity": "sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.11.tgz", + "integrity": "sha512-42zIfRI08/7bQqczAy7sY2JqZYEv3a1eNa4fLFdtJ54vNevbBIRSEA3fZgRqWFNHalh5ohsBXdrYgFqaRIuCcQ==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.18.tgz", + "integrity": "sha512-qjozwnwYmAIdrsVGrJk+hnF1WBois54IhZR6gO0wtZQoTvWL/GtiA2F31TIgAhF0ayUiZhztOv1RfC7YyrZGDQ==", + "dependencies": { + "@firebase/app-check": "0.8.11", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==" + }, + "node_modules/@firebase/app-check/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app-compat": { + "version": "0.2.48", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.48.tgz", + "integrity": "sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw==", + "dependencies": { + "@firebase/app": "0.10.18", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" + }, + "node_modules/@firebase/app/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/auth": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.2.tgz", + "integrity": "sha512-q+071y2LWe0bVnjqaX3BscqZwzdP0GKN2YBKapLq4bV88MPfCtWwGKmDhNDEDUmioOjudGXkUY5cvvKqk3mlUg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.17.tgz", + "integrity": "sha512-Shi6rqLqzU9KLXnUCmlLvVByq1kiG3oe7Wpbf5m1CgS7NiRx2pSSn0HLaRRozdkaizNzMGGj+3oHmNYQ7kU6xA==", + "dependencies": { + "@firebase/auth": "1.8.2", + "@firebase/auth-types": "0.12.3", + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==" + }, + "node_modules/@firebase/auth-types": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", + "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/auth/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "dependencies": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/component/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/data-connect": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.2.0.tgz", + "integrity": "sha512-7OrZtQoLSk2fiGijhIdUnTSqEFti3h1EMhw9nNiSZ6jJGduw4Pz6jrVvxjpZJtGH/JiljbMkBnPBS2h8CTRKEw==", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/data-connect/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/database": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.11.tgz", + "integrity": "sha512-gLrw/XeioswWUXgpVKCPAzzoOuvYNqK5fRUeiJTzO7Mlp9P6ylFEyPJlRBl1djqYye641r3MX6AmIeMXwjgwuQ==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.2.tgz", + "integrity": "sha512-5zvdnMsfDHvrQAVM6jBS7CkBpu+z3YbpFdhxRsrK1FP45IEfxlzpeuEUb17D/tpM10vfq4Ok0x5akIBaCv7gfA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/database": "1.0.11", + "@firebase/database-types": "1.0.8", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/database-types": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.8.tgz", + "integrity": "sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g==", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.3" + } + }, + "node_modules/@firebase/database/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/firestore": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.6.tgz", + "integrity": "sha512-aVDboR+upR/44qZDLR4tnZ9pepSOFBbDJnwk7eWzmTyQq2nZAVG+HIhrqpQawmUVcDRkuJv2K2UT2+oqR8F8TA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.41", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.41.tgz", + "integrity": "sha512-J/PgWKEt0yugETOE7lOabT16hsV21cLzSxERD7ZhaiwBQkBTSf0Mx9RhjZRT0Ttqe4weM90HGZFyUBqYA73fVA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/firestore": "4.7.6", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/firestore/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/functions": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.1.tgz", + "integrity": "sha512-QucRiFrvMMmIGTRhL7ZK2IeBnAWP7lAmfFREMpEtX47GjVqDqGxdFs+Mg7XBzxSc9UjDO4Rxf+aE9xJHU6bGwg==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.18.tgz", + "integrity": "sha512-N7+RN5GVus2ORB8cqfSNhfSn4iaYws6F8uCCfn4mtjC7zYS/KH6muzNAhZUdUqlv5YazbVmvxlAoYYF39i8Qzg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/functions": "0.12.1", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==" + }, + "node_modules/@firebase/functions/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/installations": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.12.tgz", + "integrity": "sha512-ES/WpuAV2k2YtBTvdaknEo7IY8vaGjIjS3zhnHSAIvY9KwTR8XZFXOJoZ3nSkjN1A5R4MtEh+07drnzPDg9vaw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.12.tgz", + "integrity": "sha512-RhcGknkxmFu92F6Jb3rXxv6a4sytPjJGifRZj8MSURPuv2Xu+/AispCXEfY1ZraobhEHTG5HLGsP6R4l9qB5aA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/messaging": { + "version": "0.12.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.16.tgz", + "integrity": "sha512-VJ8sCEIeP3+XkfbJA7410WhYGHdloYFZXoHe/vt+vNVDGw8JQPTQSVTRvjrUprEf5I4Tbcnpr2H34lS6zhCHSA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.16.tgz", + "integrity": "sha512-9HZZ88Ig3zQ0ok/Pwt4gQcNsOhoEy8hDHoGsV1am6ulgMuGuDVD2gl11Lere2ksL+msM12Lddi2x/7TCqmODZw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/messaging": "0.12.16", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==" + }, + "node_modules/@firebase/messaging/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/performance": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.12.tgz", + "integrity": "sha512-8mYL4z2jRlKXAi2hjk4G7o2sQLnJCCuTbyvti/xmHf5ZvOIGB01BZec0aDuBIXO+H1MLF62dbye/k91Fr+yc8g==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.12.tgz", + "integrity": "sha512-DyCbDTIwtBTGsEiQxTz/TD23a0na2nrDozceQ5kVkszyFYvliB0YK/9el0wAGIG91SqgTG9pxHtYErzfZc0VWw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.6.12", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==" + }, + "node_modules/@firebase/performance/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/remote-config": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.5.0.tgz", + "integrity": "sha512-weiEbpBp5PBJTHUWR4GwI7ZacaAg68BKha5QnZ8Go65W4oQjEWqCW/rfskABI/OkrGijlL3CUmCB/SA6mVo0qA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.12.tgz", + "integrity": "sha512-91jLWPtubIuPBngg9SzwvNCWzhMLcyBccmt7TNZP+y1cuYFNOWWHKUXQ3IrxCLB7WwLqQaEu7fTDAjHsTyBsSw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.5.0", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==" + }, + "node_modules/@firebase/remote-config/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/storage": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.5.tgz", + "integrity": "sha512-sB/7HNuW0N9tITyD0RxVLNCROuCXkml5i/iPqjwOGKC0xiUfpCOjBE+bb0ABMoN1qYZfqk0y9IuI2TdomjmkNw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.15.tgz", + "integrity": "sha512-Z9afjrK2O9o1ZHWCpprCGZ1BTc3BbvpZvi6tkSteC8H3W/fMM6x+RoSunlzD3hEVV5bkbwdJIqNClLMchvyoPA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/storage": "0.13.5", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/storage/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/vertexai": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.3.tgz", + "integrity": "sha512-SQHg/RPb3LwQs/xiLcvAZYz9NXyDSZUIIwvgsKh6e4wdULAfyPCZIu6Y2ZYIhZLfk9Q44cKZ+++7RPTaqQJdYA==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/vertexai/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==" + }, "node_modules/@google/generative-ai": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.18.0.tgz", @@ -2659,6 +3359,35 @@ "node": ">=18.0.0" } }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "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" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -2777,6 +3506,197 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/get-packages/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@manypkg/get-packages/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@mistralai/mistralai": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.4.0.tgz", + "integrity": "sha512-xA3DAtIDh4Qgr1EoSuiGVE+2ABNrxpcTeC0kSXYbkDNUGdthalLAH7DgbG0fkKZ7TN8xdWXQq2WiIghp/O96Eg==", + "peerDependencies": { + "zod": ">= 3" + } + }, "node_modules/@mixmark-io/domino": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", @@ -2840,6 +3760,60 @@ "node": ">=14" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@puppeteer/browsers": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", @@ -4534,11 +5508,26 @@ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "license": "MIT" }, + "node_modules/@types/chai": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.1.tgz", + "integrity": "sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA==", + "dev": true, + "dependencies": { + "@types/deep-eql": "*" + } + }, "node_modules/@types/clone-deep": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/clone-deep/-/clone-deep-4.0.4.tgz", "integrity": "sha512-vXh6JuuaAha6sqEbJueYdh5zNBPPgG1OYumuz2UvLvriN6ABHDSW8ludREGWJb1MLIzbwZn4q4zUbUCerJTJfA==" }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true + }, "node_modules/@types/diff": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz", @@ -4546,6 +5535,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/get-folder-size": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/get-folder-size/-/get-folder-size-3.0.4.tgz", + "integrity": "sha512-tSf/k7Undx6jKRwpChR9tl+0ZPf0BVwkjBRtJ5qSnz6iWm2ZRYMAS2MktC2u7YaTAFHmxpL/LBxI85M7ioJCSg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -4585,12 +5583,6 @@ "integrity": "sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg==", "license": "MIT" }, - "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", - "license": "MIT" - }, "node_modules/@types/should": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/@types/should/-/should-11.2.0.tgz", @@ -4655,6 +5647,15 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/parser": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", @@ -4793,6 +5794,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5130,6 +6140,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", @@ -5269,6 +6288,19 @@ "node": ">=10.0.0" } }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -5441,6 +6473,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -5479,6 +6512,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5509,6 +6560,25 @@ "node": ">=8" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/cheerio": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", @@ -5580,6 +6650,22 @@ "devtools-protocol": "*" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -5769,9 +6855,9 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -5903,6 +6989,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5926,6 +7024,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -6000,6 +7099,16 @@ "node": ">= 0.8" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/devtools-protocol": { "version": "0.0.1342118", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", @@ -6183,6 +7292,33 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -6270,6 +7406,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" @@ -6282,6 +7419,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6525,6 +7663,15 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6746,6 +7893,41 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -6838,6 +8020,17 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -6916,6 +8109,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.2.0.tgz", + "integrity": "sha512-ztwPhBLAZMVNZjBeQzzTM4rk2rsRXmdFYcnvjAXh+StbiFVshHKaPO9VRGMUzF48du4Mkz6jN1wkmYCuUJPxLA==", + "dependencies": { + "@firebase/analytics": "0.10.11", + "@firebase/analytics-compat": "0.2.17", + "@firebase/app": "0.10.18", + "@firebase/app-check": "0.8.11", + "@firebase/app-check-compat": "0.3.18", + "@firebase/app-compat": "0.2.48", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.8.2", + "@firebase/auth-compat": "0.5.17", + "@firebase/data-connect": "0.2.0", + "@firebase/database": "1.0.11", + "@firebase/database-compat": "2.0.2", + "@firebase/firestore": "4.7.6", + "@firebase/firestore-compat": "0.3.41", + "@firebase/functions": "0.12.1", + "@firebase/functions-compat": "0.3.18", + "@firebase/installations": "0.6.12", + "@firebase/installations-compat": "0.2.12", + "@firebase/messaging": "0.12.16", + "@firebase/messaging-compat": "0.2.16", + "@firebase/performance": "0.6.12", + "@firebase/performance-compat": "0.2.12", + "@firebase/remote-config": "0.5.0", + "@firebase/remote-config-compat": "0.2.12", + "@firebase/storage": "0.13.5", + "@firebase/storage-compat": "0.3.15", + "@firebase/util": "1.10.3", + "@firebase/vertexai": "1.0.3" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -7076,6 +8304,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7198,10 +8427,32 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-folder-size": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-5.0.0.tgz", + "integrity": "sha512-+fgtvbL83tSDypEK+T411GDBQVQtxv+qtQgbV+HVa/TYubqDhNd5ghH/D6cOHY9iC5/88GtOZB7WI8PXy2A3bg==", + "license": "MIT", + "bin": { + "get-folder-size": "bin/get-folder-size.js" + }, + "engines": { + "node": ">=18.11.0" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -7399,6 +8650,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, "node_modules/google-auth-library": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz", @@ -7419,6 +8678,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" @@ -7476,6 +8736,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -7488,6 +8749,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7500,6 +8762,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7534,6 +8797,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -7601,6 +8865,11 @@ "node": ">= 0.8" } }, + "node_modules/http-parser-js": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==" + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -7627,6 +8896,13 @@ "node": ">= 14" } }, + "node_modules/human-id": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", + "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", + "dev": true, + "license": "MIT" + }, "node_modules/human-signals": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", @@ -7645,6 +8921,21 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -7657,6 +8948,11 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -7678,10 +8974,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "license": "MIT", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", "engines": { "node": ">= 4" } @@ -8072,6 +9367,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", @@ -8130,6 +9438,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -8401,6 +9719,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -8408,6 +9731,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -8425,6 +9755,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==" + }, "node_modules/lop": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.1.tgz", @@ -8436,6 +9771,15 @@ "underscore": "^1.13.1" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", @@ -8848,6 +10192,16 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -9038,9 +10392,9 @@ "license": "MIT" }, "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "license": "MIT", "dependencies": { @@ -9199,6 +10553,7 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9262,28 +10617,30 @@ } }, "node_modules/openai": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.61.0.tgz", - "integrity": "sha512-xkygRBRLIUumxzKGb1ug05pWmJROQsHkGuj/N6Jiw2dj0dI19JvbFpErSZKmJ/DA+0IvpcugZqCAyk8iLpyM6Q==", + "version": "4.82.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.82.0.tgz", + "integrity": "sha512-1bTxOVGZuVGsKKUWbh3BEwX1QxIXUftJv+9COhhGGVDTFwiaOd4gWsMynF2ewj1mg6by3/O+U8+EEHpWRdPaJg==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", - "@types/qs": "^6.9.15", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "qs": "^6.10.3" + "node-fetch": "^2.6.7" }, "bin": { "openai": "bin/cli" }, "peerDependencies": { + "ws": "^8.18.0", "zod": "^3.23.8" }, "peerDependenciesMeta": { + "ws": { + "optional": true + }, "zod": { "optional": true } @@ -9429,6 +10786,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -9461,6 +10848,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-timeout": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", @@ -9473,6 +10870,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-wait-for": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", @@ -9527,6 +10934,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.8.tgz", + "integrity": "sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==", + "dev": true, + "license": "MIT" + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -9672,6 +11086,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pdf-parse": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz", @@ -9700,6 +11123,13 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -9801,6 +11231,29 @@ "node": ">=0.4.0" } }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "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" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-agent": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", @@ -9884,21 +11337,6 @@ "node": ">=18" } }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9978,6 +11416,56 @@ "node": ">=4" } }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/read-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -10006,6 +11494,13 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -10291,6 +11786,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -10438,6 +11934,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -10464,6 +11961,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-git": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -10524,6 +12036,17 @@ "node": ">=0.10.0" } }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -10881,6 +12404,19 @@ "streamx": "^2.15.0" } }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -10964,6 +12500,19 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11036,6 +12585,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -11203,9 +12761,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", "license": "MIT", "engines": { "node": ">=18.17" @@ -11317,6 +12875,27 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", diff --git a/package.json b/package.json index 574e57c3a6..f33033f379 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "claude-dev", - "displayName": "Cline (prev. Claude Dev)", + "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.6", + "version": "3.2.12", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", @@ -51,7 +51,7 @@ { "id": "claude-dev-ActivityBar", "title": "Cline", - "icon": "$(robot)" + "icon": "assets/icons/icon.svg" } ] }, @@ -124,6 +124,45 @@ "when": "view == claude-dev.SidebarProvider" } ] + }, + "configuration": { + "title": "Cline", + "properties": { + "cline.vsCodeLmModelSelector": { + "type": "object", + "properties": { + "vendor": { + "type": "string", + "description": "The vendor of the language model (e.g. copilot)" + }, + "family": { + "type": "string", + "description": "The family of the language model (e.g. gpt-4)" + } + }, + "description": "Settings for VSCode Language Model API" + }, + "cline.mcp.mode": { + "type": "string", + "enum": [ + "full", + "server-use-only", + "off" + ], + "enumDescriptions": [ + "Enable all MCP functionality (server use and build instructions)", + "Enable MCP server use only (excludes instructions about building MCP servers)", + "Disable all MCP functionality" + ], + "default": "full", + "description": "Controls MCP inclusion in prompts, reduces token usage if you only need access to certain functionality." + }, + "cline.enableCheckpoints": { + "type": "boolean", + "default": true, + "description": "Enables extension to save checkpoints of workspace throughout the task." + } + } } }, "scripts": { @@ -145,9 +184,15 @@ "start:webview": "cd webview-ui && npm run start", "build:webview": "cd webview-ui && npm run build", "test:webview": "cd webview-ui && npm run test", - "publish:marketplace": "vsce publish && ovsx publish" + "publish:marketplace": "vsce publish && ovsx publish", + "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", + "prepare": "husky", + "changeset": "changeset", + "version-packages": "changeset version" }, "devDependencies": { + "@changesets/cli": "^2.27.12", + "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", "@types/node": "20.x", @@ -157,8 +202,10 @@ "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", + "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -169,8 +216,10 @@ "@anthropic-ai/sdk": "^0.26.0", "@anthropic-ai/vertex-sdk": "^0.4.1", "@google/generative-ai": "^0.18.0", + "@mistralai/mistralai": "^1.3.6", "@modelcontextprotocol/sdk": "^1.0.1", "@types/clone-deep": "^4.0.4", + "@types/get-folder-size": "^3.0.4", "@types/pdf-parse": "^1.1.4", "@types/turndown": "^5.0.5", "@vscode/codicons": "^0.0.36", @@ -183,17 +232,21 @@ "diff": "^5.2.0", "execa": "^9.5.2", "fast-deep-equal": "^3.1.3", + "firebase": "^11.2.0", + "get-folder-size": "^5.0.0", "globby": "^14.0.2", + "ignore": "^7.0.3", "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", "monaco-vscode-textmate-theme-converter": "^0.1.7", - "openai": "^4.61.0", + "openai": "^4.82.0", "os-name": "^6.0.0", "p-wait-for": "^5.0.2", "pdf-parse": "^1.1.1", "puppeteer-chromium-resolver": "^23.0.0", "puppeteer-core": "^23.4.0", "serialize-error": "^11.0.3", + "simple-git": "^3.27.0", "strip-ansi": "^7.1.0", "tree-sitter-wasms": "^0.1.11", "turndown": "^7.2.0", diff --git a/src/api/index.ts b/src/api/index.ts index ec35c2a2af..5ed9e6de8c 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -10,12 +10,20 @@ import { LmStudioHandler } from "./providers/lmstudio" import { GeminiHandler } from "./providers/gemini" import { OpenAiNativeHandler } from "./providers/openai-native" import { ApiStream } from "./transform/stream" +import { DeepSeekHandler } from "./providers/deepseek" +import { MistralHandler } from "./providers/mistral" +import { VsCodeLmHandler } from "./providers/vscode-lm" +import { LiteLlmHandler } from "./providers/litellm" export interface ApiHandler { createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream getModel(): { id: string; info: ModelInfo } } +export interface SingleCompletionHandler { + completePrompt(prompt: string): Promise +} + export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { const { apiProvider, ...options } = configuration switch (apiProvider) { @@ -37,6 +45,14 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { return new GeminiHandler(options) case "openai-native": return new OpenAiNativeHandler(options) + case "deepseek": + return new DeepSeekHandler(options) + case "mistral": + return new MistralHandler(options) + case "vscode-lm": + return new VsCodeLmHandler(options) + case "litellm": + return new LiteLlmHandler(options) default: return new AnthropicHandler(options) } diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index c090f17c63..8c3fd1b87d 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -1,12 +1,6 @@ import { Anthropic } from "@anthropic-ai/sdk" import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming" -import { - anthropicDefaultModelId, - AnthropicModelId, - anthropicModels, - ApiHandlerOptions, - ModelInfo, -} from "../../shared/api" +import { anthropicDefaultModelId, AnthropicModelId, anthropicModels, ApiHandlerOptions, ModelInfo } from "../../shared/api" import { ApiHandler } from "../index" import { ApiStream } from "../transform/stream" @@ -23,8 +17,9 @@ export class AnthropicHandler implements ApiHandler { } async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const model = this.getModel() let stream: AnthropicStream - const modelId = this.getModel().id + const modelId = model.id switch (modelId) { // 'latest' alias does not support cache_control case "claude-3-5-sonnet-20241022": @@ -43,9 +38,15 @@ export class AnthropicHandler implements ApiHandler { stream = await this.client.beta.promptCaching.messages.create( { model: modelId, - max_tokens: this.getModel().info.maxTokens || 8192, + max_tokens: model.info.maxTokens || 8192, temperature: 0, - system: [{ text: systemPrompt, type: "text", cache_control: { type: "ephemeral" } }], // setting cache breakpoint for system prompt so new tasks can reuse it + system: [ + { + text: systemPrompt, + type: "text", + cache_control: { type: "ephemeral" }, + }, + ], // setting cache breakpoint for system prompt so new tasks can reuse it messages: messages.map((message, index) => { if (index === lastUserMsgIndex || index === secondLastMsgUserIndex) { return { @@ -56,12 +57,19 @@ export class AnthropicHandler implements ApiHandler { { type: "text", text: message.content, - cache_control: { type: "ephemeral" }, + cache_control: { + type: "ephemeral", + }, }, ] : message.content.map((content, contentIndex) => contentIndex === message.content.length - 1 - ? { ...content, cache_control: { type: "ephemeral" } } + ? { + ...content, + cache_control: { + type: "ephemeral", + }, + } : content, ), } @@ -83,7 +91,9 @@ export class AnthropicHandler implements ApiHandler { case "claude-3-opus-20240229": case "claude-3-haiku-20240307": return { - headers: { "anthropic-beta": "prompt-caching-2024-07-31" }, + headers: { + "anthropic-beta": "prompt-caching-2024-07-31", + }, } default: return undefined @@ -95,7 +105,7 @@ export class AnthropicHandler implements ApiHandler { default: { stream = (await this.client.messages.create({ model: modelId, - max_tokens: this.getModel().info.maxTokens || 8192, + max_tokens: model.info.maxTokens || 8192, temperature: 0, system: [{ text: systemPrompt, type: "text" }], messages, @@ -171,6 +181,9 @@ export class AnthropicHandler implements ApiHandler { const id = modelId as AnthropicModelId return { id, info: anthropicModels[id] } } - return { id: anthropicDefaultModelId, info: anthropicModels[anthropicDefaultModelId] } + return { + id: anthropicDefaultModelId, + info: anthropicModels[anthropicDefaultModelId], + } } } diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index 58f75ad4ac..a82a71b8ef 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -107,6 +107,9 @@ export class AwsBedrockHandler implements ApiHandler { const id = modelId as BedrockModelId return { id, info: bedrockModels[id] } } - return { id: bedrockDefaultModelId, info: bedrockModels[bedrockDefaultModelId] } + return { + id: bedrockDefaultModelId, + info: bedrockModels[bedrockDefaultModelId], + } } } diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts new file mode 100644 index 0000000000..763e1ae68f --- /dev/null +++ b/src/api/providers/deepseek.ts @@ -0,0 +1,86 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" +import { ApiHandler } from "../" +import { ApiHandlerOptions, DeepSeekModelId, ModelInfo, deepSeekDefaultModelId, deepSeekModels } from "../../shared/api" +import { convertToOpenAiMessages } from "../transform/openai-format" +import { ApiStream } from "../transform/stream" +import { convertToR1Format } from "../transform/r1-format" + +export class DeepSeekHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: OpenAI + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new OpenAI({ + baseURL: "https://api.deepseek.com/v1", + apiKey: this.options.deepSeekApiKey, + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const model = this.getModel() + + const isDeepseekReasoner = model.id.includes("deepseek-reasoner") + + let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages), + ] + + if (isDeepseekReasoner) { + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + } + + const stream = await this.client.chat.completions.create({ + model: model.id, + max_completion_tokens: model.info.maxTokens, + messages: openAiMessages, + stream: true, + stream_options: { include_usage: true }, + // Only set temperature for non-reasoner models + ...(model.id === "deepseek-reasoner" ? {} : { temperature: 0 }), + }) + + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + + if (delta && "reasoning_content" in delta && delta.reasoning_content) { + yield { + type: "reasoning", + reasoning: (delta.reasoning_content as string | undefined) || "", + } + } + + if (chunk.usage) { + yield { + type: "usage", + inputTokens: chunk.usage.prompt_tokens || 0, // (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) where the input tokens is the sum of the cache hits/misses, while anthropic reports them as separate tokens. This is important to know for 1) context management truncation algorithm, and 2) cost calculation (NOTE: we report both input and cache stats but for now set input price to 0 since all the cost calculation will be done using cache hits/misses) + outputTokens: chunk.usage.completion_tokens || 0, + // @ts-ignore-next-line + cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, + // @ts-ignore-next-line + cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, + } + } + } + } + + getModel(): { id: DeepSeekModelId; info: ModelInfo } { + const modelId = this.options.apiModelId + if (modelId && modelId in deepSeekModels) { + const id = modelId as DeepSeekModelId + return { id, info: deepSeekModels[id] } + } + return { + id: deepSeekDefaultModelId, + info: deepSeekModels[deepSeekDefaultModelId], + } + } +} diff --git a/src/api/providers/gemini.ts b/src/api/providers/gemini.ts index d7ac5ec67d..39c55548d1 100644 --- a/src/api/providers/gemini.ts +++ b/src/api/providers/gemini.ts @@ -51,6 +51,9 @@ export class GeminiHandler implements ApiHandler { const id = modelId as GeminiModelId return { id, info: geminiModels[id] } } - return { id: geminiDefaultModelId, info: geminiModels[geminiDefaultModelId] } + return { + id: geminiDefaultModelId, + info: geminiModels[geminiDefaultModelId], + } } } diff --git a/src/api/providers/litellm.ts b/src/api/providers/litellm.ts new file mode 100644 index 0000000000..80ad5e2c75 --- /dev/null +++ b/src/api/providers/litellm.ts @@ -0,0 +1,60 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" +import { ApiHandlerOptions, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "../../shared/api" +import { ApiHandler } from ".." +import { ApiStream } from "../transform/stream" +import { convertToOpenAiMessages } from "../transform/openai-format" + +export class LiteLlmHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: OpenAI + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new OpenAI({ + baseURL: this.options.liteLlmBaseUrl || "http://localhost:4000", + apiKey: "not-needed", + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const formattedMessages = convertToOpenAiMessages(messages) + const systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = { + role: "system", + content: systemPrompt, + } + + const stream = await this.client.chat.completions.create({ + model: this.options.liteLlmModelId || liteLlmDefaultModelId, + messages: [systemMessage, ...formattedMessages], + temperature: 0, + stream: true, + stream_options: { include_usage: true }, + }) + + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + + if (chunk.usage) { + yield { + type: "usage", + inputTokens: chunk.usage.prompt_tokens || 0, + outputTokens: chunk.usage.completion_tokens || 0, + } + } + } + } + + getModel() { + return { + id: this.options.liteLlmModelId || liteLlmDefaultModelId, + info: liteLlmModelInfoSaneDefaults, + } + } +} diff --git a/src/api/providers/mistral.ts b/src/api/providers/mistral.ts new file mode 100644 index 0000000000..5be89b18f3 --- /dev/null +++ b/src/api/providers/mistral.ts @@ -0,0 +1,74 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import { Mistral } from "@mistralai/mistralai" +import { ApiHandler } from "../" +import { + ApiHandlerOptions, + mistralDefaultModelId, + MistralModelId, + mistralModels, + ModelInfo, + openAiNativeDefaultModelId, + OpenAiNativeModelId, + openAiNativeModels, +} from "../../shared/api" +import { convertToMistralMessages } from "../transform/mistral-format" +import { ApiStream } from "../transform/stream" + +export class MistralHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: Mistral + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new Mistral({ + serverURL: "https://api.mistral.ai", + apiKey: this.options.mistralApiKey, + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const stream = await this.client.chat.stream({ + model: this.getModel().id, + // max_completion_tokens: this.getModel().info.maxTokens, + temperature: 0, + messages: [{ role: "system", content: systemPrompt }, ...convertToMistralMessages(messages)], + stream: true, + }) + + for await (const chunk of stream) { + const delta = chunk.data.choices[0]?.delta + if (delta?.content) { + let content: string = "" + if (typeof delta.content === "string") { + content = delta.content + } else if (Array.isArray(delta.content)) { + content = delta.content.map((c) => (c.type === "text" ? c.text : "")).join("") + } + yield { + type: "text", + text: content, + } + } + + if (chunk.data.usage) { + yield { + type: "usage", + inputTokens: chunk.data.usage.promptTokens || 0, + outputTokens: chunk.data.usage.completionTokens || 0, + } + } + } + } + + getModel(): { id: MistralModelId; info: ModelInfo } { + const modelId = this.options.apiModelId + if (modelId && modelId in mistralModels) { + const id = modelId as MistralModelId + return { id, info: mistralModels[id] } + } + return { + id: mistralDefaultModelId, + info: mistralModels[mistralDefaultModelId], + } + } +} diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index 70d55b7abe..8a47ec4345 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -24,6 +24,7 @@ export class OpenAiNativeHandler implements ApiHandler { async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { switch (this.getModel().id) { + case "o1": case "o1-preview": case "o1-mini": { // o1 doesnt support streaming, non-1 temp, or system prompt @@ -42,6 +43,31 @@ export class OpenAiNativeHandler implements ApiHandler { } break } + case "o3-mini": { + const stream = await this.client.chat.completions.create({ + model: this.getModel().id, + messages: [{ role: "developer", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + stream: true, + stream_options: { include_usage: true }, + }) + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + if (chunk.usage) { + yield { + type: "usage", + inputTokens: chunk.usage.prompt_tokens || 0, + outputTokens: chunk.usage.completion_tokens || 0, + } + } + } + break + } default: { const stream = await this.client.chat.completions.create({ model: this.getModel().id, @@ -80,6 +106,9 @@ export class OpenAiNativeHandler implements ApiHandler { const id = modelId as OpenAiNativeModelId return { id, info: openAiNativeModels[id] } } - return { id: openAiNativeDefaultModelId, info: openAiNativeModels[openAiNativeDefaultModelId] } + return { + id: openAiNativeDefaultModelId, + info: openAiNativeModels[openAiNativeDefaultModelId], + } } } diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 57cab17e68..fd73abb567 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -1,14 +1,10 @@ import { Anthropic } from "@anthropic-ai/sdk" import OpenAI, { AzureOpenAI } from "openai" -import { - ApiHandlerOptions, - azureOpenAiDefaultApiVersion, - ModelInfo, - openAiModelInfoSaneDefaults, -} from "../../shared/api" +import { ApiHandlerOptions, azureOpenAiDefaultApiVersion, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" import { ApiHandler } from "../index" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" +import { convertToR1Format } from "../transform/r1-format" export class OpenAiHandler implements ApiHandler { private options: ApiHandlerOptions @@ -32,12 +28,20 @@ export class OpenAiHandler implements ApiHandler { } async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { - const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + const modelId = this.options.openAiModelId ?? "" + const isDeepseekReasoner = modelId.includes("deepseek-reasoner") + + let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), ] + + if (isDeepseekReasoner) { + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + } + const stream = await this.client.chat.completions.create({ - model: this.options.openAiModelId ?? "", + model: modelId, messages: openAiMessages, temperature: 0, stream: true, @@ -51,6 +55,14 @@ export class OpenAiHandler implements ApiHandler { text: delta.content, } } + + if (delta && "reasoning_content" in delta && delta.reasoning_content) { + yield { + type: "reasoning", + reasoning: (delta.reasoning_content as string | undefined) || "", + } + } + if (chunk.usage) { yield { type: "usage", diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 8d37cdf0a3..6b8f40c5e7 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -1,11 +1,12 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" +import delay from "delay" import OpenAI from "openai" import { ApiHandler } from "../" import { ApiHandlerOptions, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" -import delay from "delay" +import { convertToR1Format } from "../transform/r1-format" export class OpenRouterHandler implements ApiHandler { private options: ApiHandlerOptions @@ -24,15 +25,17 @@ export class OpenRouterHandler implements ApiHandler { } async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const model = this.getModel() + // Convert Anthropic messages to OpenAI format - const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), ] // prompt caching: https://openrouter.ai/docs/prompt-caching // this is specifically for claude models (some models may 'support prompt caching' automatically without this) - switch (this.getModel().id) { + switch (model.id) { case "anthropic/claude-3.5-sonnet": case "anthropic/claude-3.5-sonnet:beta": case "anthropic/claude-3.5-sonnet-20240620": @@ -83,7 +86,7 @@ export class OpenRouterHandler implements ApiHandler { // Not sure how openrouter defaults max tokens when no value is provided, but the anthropic api requires this value and since they offer both 4096 and 8192 variants, we should ensure 8192. // (models usually default to max tokens allowed) let maxTokens: number | undefined - switch (this.getModel().id) { + switch (model.id) { case "anthropic/claude-3.5-sonnet": case "anthropic/claude-3.5-sonnet:beta": case "anthropic/claude-3.5-sonnet-20240620": @@ -96,17 +99,35 @@ export class OpenRouterHandler implements ApiHandler { break } + let temperature = 0 + let topP: number | undefined = undefined + // Handle models based on deepseek-r1 + if (this.getModel().id.startsWith("deepseek/deepseek-r1") || this.getModel().id === "perplexity/sonar-reasoning") { + // Recommended temperature for DeepSeek reasoning models + temperature = 0.6 + // DeepSeek highly recommends using user instead of system role + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + // Some provider support topP and 0.95 is value that Deepseek used in their benchmarks + topP = 0.95 + } + // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. - const shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + let shouldApplyMiddleOutTransform = !model.info.supportsPromptCache + // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window (FIXME: once we have a more robust token estimator we should not rely on this) + if (model.id === "deepseek/deepseek-chat") { + shouldApplyMiddleOutTransform = true + } // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ - model: this.getModel().id, + model: model.id, max_tokens: maxTokens, - temperature: 0, + temperature: temperature, + top_p: topP, messages: openAiMessages, stream: true, transforms: shouldApplyMiddleOutTransform ? ["middle-out"] : undefined, + include_reasoning: true, }) let genId: string | undefined @@ -130,6 +151,37 @@ export class OpenRouterHandler implements ApiHandler { text: delta.content, } } + + // Reasoning tokens are returned separately from the content + if ("reasoning" in delta && delta.reasoning) { + // console.log("reasoning", delta.reasoning) + yield { + type: "reasoning", + // @ts-ignore-next-line + reasoning: delta.reasoning, + } + + // if (didStreamThinkTagInReasoning) { + // yield { + // type: "text", + // // @ts-ignore-next-line + // text: delta.reasoning, + // } + // } else { + // yield { + // type: "reasoning", + // // @ts-ignore-next-line + // text: delta.reasoning, + // } + + // // @ts-ignore-next-line + // reasoningResponse += delta.reasoning + // if (reasoningResponse.includes("")) { + // didStreamThinkTagInReasoning = true + // console.log("did hit think tag", reasoningResponse) + // } + // } + } // if (chunk.usage) { // yield { // type: "usage", diff --git a/src/api/providers/vertex.ts b/src/api/providers/vertex.ts index 60e6967dd6..c8f1efd873 100644 --- a/src/api/providers/vertex.ts +++ b/src/api/providers/vertex.ts @@ -81,6 +81,9 @@ export class VertexHandler implements ApiHandler { const id = modelId as VertexModelId return { id, info: vertexModels[id] } } - return { id: vertexDefaultModelId, info: vertexModels[vertexDefaultModelId] } + return { + id: vertexDefaultModelId, + info: vertexModels[vertexDefaultModelId], + } } } diff --git a/src/api/providers/vscode-lm.ts b/src/api/providers/vscode-lm.ts new file mode 100644 index 0000000000..f28075f1da --- /dev/null +++ b/src/api/providers/vscode-lm.ts @@ -0,0 +1,639 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import * as vscode from "vscode" +import { ApiHandler, SingleCompletionHandler } from "../" +import { calculateApiCost } from "../../utils/cost" +import { ApiStream } from "../transform/stream" +import { convertToVsCodeLmMessages } from "../transform/vscode-lm-format" +import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "../../shared/vsCodeSelectorUtils" +import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" + +// Cline does not update VSCode type definitions or engine requirements to maintain compatibility. +// This declaration (as seen in src/integrations/TerminalManager.ts) provides types for the Language Model API in newer versions of VSCode. +// Extracted from https://github.com/microsoft/vscode/blob/131ee0ef660d600cd0a7e6058375b281553abe20/src/vscode-dts/vscode.d.ts +declare module "vscode" { + enum LanguageModelChatMessageRole { + User = 1, + Assistant = 2, + } + enum LanguageModelChatToolMode { + Auto = 1, + Required = 2, + } + interface LanguageModelChatSelector { + vendor?: string + family?: string + version?: string + id?: string + } + interface LanguageModelChatTool { + name: string + description: string + inputSchema?: object + } + interface LanguageModelChatRequestOptions { + justification?: string + modelOptions?: { [name: string]: any } + tools?: LanguageModelChatTool[] + toolMode?: LanguageModelChatToolMode + } + class LanguageModelTextPart { + value: string + constructor(value: string) + } + class LanguageModelToolCallPart { + callId: string + name: string + input: object + constructor(callId: string, name: string, input: object) + } + interface LanguageModelChatResponse { + stream: AsyncIterable + text: AsyncIterable + } + interface LanguageModelChat { + readonly name: string + readonly id: string + readonly vendor: string + readonly family: string + readonly version: string + readonly maxInputTokens: number + + sendRequest( + messages: LanguageModelChatMessage[], + options?: LanguageModelChatRequestOptions, + token?: CancellationToken, + ): Thenable + countTokens(text: string | LanguageModelChatMessage, token?: CancellationToken): Thenable + } + class LanguageModelPromptTsxPart { + value: unknown + constructor(value: unknown) + } + class LanguageModelToolResultPart { + callId: string + content: Array + constructor(callId: string, content: Array) + } + class LanguageModelChatMessage { + static User( + content: string | Array, + name?: string, + ): LanguageModelChatMessage + static Assistant( + content: string | Array, + name?: string, + ): LanguageModelChatMessage + + role: LanguageModelChatMessageRole + content: Array + name: string | undefined + + constructor( + role: LanguageModelChatMessageRole, + content: string | Array, + name?: string, + ) + } + namespace lm { + function selectChatModels(selector?: LanguageModelChatSelector): Thenable + } +} + +/** + * Handles interaction with VS Code's Language Model API for chat-based operations. + * This handler implements the ApiHandler interface to provide VS Code LM specific functionality. + * + * @implements {ApiHandler} + * + * @remarks + * The handler manages a VS Code language model chat client and provides methods to: + * - Create and manage chat client instances + * - Stream messages using VS Code's Language Model API + * - Retrieve model information + * + * @example + * ```typescript + * const options = { + * vsCodeLmModelSelector: { vendor: "copilot", family: "gpt-4" } + * }; + * const handler = new VsCodeLmHandler(options); + * + * // Stream a conversation + * const systemPrompt = "You are a helpful assistant"; + * const messages = [{ role: "user", content: "Hello!" }]; + * for await (const chunk of handler.createMessage(systemPrompt, messages)) { + * console.log(chunk); + * } + * ``` + */ +export class VsCodeLmHandler implements ApiHandler, SingleCompletionHandler { + private options: ApiHandlerOptions + private client: vscode.LanguageModelChat | null + private disposable: vscode.Disposable | null + private currentRequestCancellation: vscode.CancellationTokenSource | null + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = null + this.disposable = null + this.currentRequestCancellation = null + + try { + // Listen for model changes and reset client + this.disposable = vscode.workspace.onDidChangeConfiguration((event) => { + if (event.affectsConfiguration("lm")) { + try { + this.client = null + this.ensureCleanState() + } catch (error) { + console.error("Error during configuration change cleanup:", error) + } + } + }) + } catch (error) { + // Ensure cleanup if constructor fails + this.dispose() + + throw new Error( + `Cline : Failed to initialize handler: ${error instanceof Error ? error.message : "Unknown error"}`, + ) + } + } + + /** + * Creates a language model chat client based on the provided selector. + * + * @param selector - Selector criteria to filter language model chat instances + * @returns Promise resolving to the first matching language model chat instance + * @throws Error when no matching models are found with the given selector + * + * @example + * const selector = { vendor: "copilot", family: "gpt-4o" }; + * const chatClient = await createClient(selector); + */ + async createClient(selector: vscode.LanguageModelChatSelector): Promise { + try { + const models = await vscode.lm.selectChatModels(selector) + + // Use first available model or create a minimal model object + if (models && Array.isArray(models) && models.length > 0) { + return models[0] + } + + // Create a minimal model if no models are available + return { + id: "default-lm", + name: "Default Language Model", + vendor: "vscode", + family: "lm", + version: "1.0", + maxInputTokens: 8192, + sendRequest: async (messages, options, token) => { + // Provide a minimal implementation + return { + stream: (async function* () { + yield new vscode.LanguageModelTextPart( + "Language model functionality is limited. Please check VS Code configuration.", + ) + })(), + text: (async function* () { + yield "Language model functionality is limited. Please check VS Code configuration." + })(), + } + }, + countTokens: async () => 0, + } + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + throw new Error(`Cline : Failed to select model: ${errorMessage}`) + } + } + + /** + * Creates and streams a message using the VS Code Language Model API. + * + * @param systemPrompt - The system prompt to initialize the conversation context + * @param messages - An array of message parameters following the Anthropic message format + * + * @yields {ApiStream} An async generator that yields either text chunks or tool calls from the model response + * + * @throws {Error} When vsCodeLmModelSelector option is not provided + * @throws {Error} When the response stream encounters an error + * + * @remarks + * This method handles the initialization of the VS Code LM client if not already created, + * converts the messages to VS Code LM format, and streams the response chunks. + * Tool calls handling is currently a work in progress. + */ + dispose(): void { + if (this.disposable) { + this.disposable.dispose() + } + + if (this.currentRequestCancellation) { + this.currentRequestCancellation.cancel() + this.currentRequestCancellation.dispose() + } + } + + private async countTokens(text: string | vscode.LanguageModelChatMessage): Promise { + // Check for required dependencies + if (!this.client) { + console.warn("Cline : No client available for token counting") + return 0 + } + + if (!this.currentRequestCancellation) { + console.warn("Cline : No cancellation token available for token counting") + return 0 + } + + // Validate input + if (!text) { + console.debug("Cline : Empty text provided for token counting") + return 0 + } + + try { + // Handle different input types + let tokenCount: number + + if (typeof text === "string") { + tokenCount = await this.client.countTokens(text, this.currentRequestCancellation.token) + } else if (text instanceof vscode.LanguageModelChatMessage) { + // For chat messages, ensure we have content + if (!text.content || (Array.isArray(text.content) && text.content.length === 0)) { + console.debug("Cline : Empty chat message content") + return 0 + } + tokenCount = await this.client.countTokens(text, this.currentRequestCancellation.token) + } else { + console.warn("Cline : Invalid input type for token counting") + return 0 + } + + // Validate the result + if (typeof tokenCount !== "number") { + console.warn("Cline : Non-numeric token count received:", tokenCount) + return 0 + } + + if (tokenCount < 0) { + console.warn("Cline : Negative token count received:", tokenCount) + return 0 + } + + return tokenCount + } catch (error) { + // Handle specific error types + if (error instanceof vscode.CancellationError) { + console.debug("Cline : Token counting cancelled by user") + return 0 + } + + const errorMessage = error instanceof Error ? error.message : "Unknown error" + console.warn("Cline : Token counting failed:", errorMessage) + + // Log additional error details if available + if (error instanceof Error && error.stack) { + console.debug("Token counting error stack:", error.stack) + } + + return 0 // Fallback to prevent stream interruption + } + } + + private async calculateTotalInputTokens( + systemPrompt: string, + vsCodeLmMessages: vscode.LanguageModelChatMessage[], + ): Promise { + const systemTokens: number = await this.countTokens(systemPrompt) + + const messageTokens: number[] = await Promise.all(vsCodeLmMessages.map((msg) => this.countTokens(msg))) + + return systemTokens + messageTokens.reduce((sum: number, tokens: number): number => sum + tokens, 0) + } + + private ensureCleanState(): void { + if (this.currentRequestCancellation) { + this.currentRequestCancellation.cancel() + this.currentRequestCancellation.dispose() + this.currentRequestCancellation = null + } + } + + private async getClient(): Promise { + if (!this.client) { + console.debug("Cline : Getting client with options:", { + vsCodeLmModelSelector: this.options.vsCodeLmModelSelector, + hasOptions: !!this.options, + selectorKeys: this.options.vsCodeLmModelSelector ? Object.keys(this.options.vsCodeLmModelSelector) : [], + }) + + try { + // Use default empty selector if none provided to get all available models + const selector = this.options?.vsCodeLmModelSelector || {} + console.debug("Cline : Creating client with selector:", selector) + this.client = await this.createClient(selector) + } catch (error) { + const message = error instanceof Error ? error.message : "Unknown error" + console.error("Cline : Client creation failed:", message) + throw new Error(`Cline : Failed to create client: ${message}`) + } + } + + return this.client + } + + private cleanTerminalOutput(text: string): string { + if (!text) { + return "" + } + + return ( + text + // Normalize line breaks + .replace(/\r\n/g, "\n") + .replace(/\r/g, "\n") + + // Remove ANSI escape sequences + .replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "") // Full set of ANSI sequences + .replace(/\x9B[0-?]*[ -/]*[@-~]/g, "") // CSI sequences + + // Remove terminal title setting sequences and other OSC sequences + .replace(/\x1B\][0-9;]*(?:\x07|\x1B\\)/g, "") + + // Remove control characters + .replace(/[\x00-\x09\x0B-\x0C\x0E-\x1F\x7F]/g, "") + + // Remove VS Code escape sequences + .replace(/\x1B[PD].*?\x1B\\/g, "") // DCS sequences + .replace(/\x1B_.*?\x1B\\/g, "") // APC sequences + .replace(/\x1B\^.*?\x1B\\/g, "") // PM sequences + .replace(/\x1B\[[\d;]*[HfABCDEFGJKST]/g, "") // Cursor movement and clear screen + + // Remove Windows paths and service information + .replace(/^(?:PS )?[A-Z]:\\[^\n]*$/gm, "") + .replace(/^;?Cwd=.*$/gm, "") + + // Clean escaped sequences + .replace(/\\x[0-9a-fA-F]{2}/g, "") + .replace(/\\u[0-9a-fA-F]{4}/g, "") + + // Final cleanup + .replace(/\n{3,}/g, "\n\n") // Remove multiple empty lines + .trim() + ) + } + + private cleanMessageContent(content: any): any { + if (!content) { + return content + } + + if (typeof content === "string") { + return this.cleanTerminalOutput(content) + } + + if (Array.isArray(content)) { + return content.map((item) => this.cleanMessageContent(item)) + } + + if (typeof content === "object") { + const cleaned: any = {} + for (const [key, value] of Object.entries(content)) { + cleaned[key] = this.cleanMessageContent(value) + } + return cleaned + } + + return content + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + // Ensure clean state before starting a new request + this.ensureCleanState() + const client: vscode.LanguageModelChat = await this.getClient() + + // Clean system prompt and messages + const cleanedSystemPrompt = this.cleanTerminalOutput(systemPrompt) + const cleanedMessages = messages.map((msg) => ({ + ...msg, + content: this.cleanMessageContent(msg.content), + })) + + // Convert Anthropic messages to VS Code LM messages + const vsCodeLmMessages: vscode.LanguageModelChatMessage[] = [ + vscode.LanguageModelChatMessage.Assistant(cleanedSystemPrompt), + ...convertToVsCodeLmMessages(cleanedMessages), + ] + + // Initialize cancellation token for the request + this.currentRequestCancellation = new vscode.CancellationTokenSource() + + // Calculate input tokens before starting the stream + const totalInputTokens: number = await this.calculateTotalInputTokens(systemPrompt, vsCodeLmMessages) + + // Accumulate the text and count at the end of the stream to reduce token counting overhead. + let accumulatedText: string = "" + + try { + // Create the response stream with minimal required options + const requestOptions: vscode.LanguageModelChatRequestOptions = { + justification: `Cline would like to use '${client.name}' from '${client.vendor}', Click 'Allow' to proceed.`, + } + + // Note: Tool support is currently provided by the VSCode Language Model API directly + // Extensions can register tools using vscode.lm.registerTool() + + const response: vscode.LanguageModelChatResponse = await client.sendRequest( + vsCodeLmMessages, + requestOptions, + this.currentRequestCancellation.token, + ) + + // Consume the stream and handle both text and tool call chunks + for await (const chunk of response.stream) { + if (chunk instanceof vscode.LanguageModelTextPart) { + // Validate text part value + if (typeof chunk.value !== "string") { + console.warn("Cline : Invalid text part value received:", chunk.value) + continue + } + + accumulatedText += chunk.value + yield { + type: "text", + text: chunk.value, + } + } else if (chunk instanceof vscode.LanguageModelToolCallPart) { + try { + // Validate tool call parameters + if (!chunk.name || typeof chunk.name !== "string") { + console.warn("Cline : Invalid tool name received:", chunk.name) + continue + } + + if (!chunk.callId || typeof chunk.callId !== "string") { + console.warn("Cline : Invalid tool callId received:", chunk.callId) + continue + } + + // Ensure input is a valid object + if (!chunk.input || typeof chunk.input !== "object") { + console.warn("Cline : Invalid tool input received:", chunk.input) + continue + } + + // Convert tool calls to text format with proper error handling + const toolCall = { + type: "tool_call", + name: chunk.name, + arguments: chunk.input, + callId: chunk.callId, + } + + const toolCallText = JSON.stringify(toolCall) + accumulatedText += toolCallText + + // Log tool call for debugging + console.debug("Cline : Processing tool call:", { + name: chunk.name, + callId: chunk.callId, + inputSize: JSON.stringify(chunk.input).length, + }) + + yield { + type: "text", + text: toolCallText, + } + } catch (error) { + console.error("Cline : Failed to process tool call:", error) + // Continue processing other chunks even if one fails + continue + } + } else { + console.warn("Cline : Unknown chunk type received:", chunk) + } + } + + // Count tokens in the accumulated text after stream completion + const totalOutputTokens: number = await this.countTokens(accumulatedText) + + // Report final usage after stream completion + yield { + type: "usage", + inputTokens: totalInputTokens, + outputTokens: totalOutputTokens, + totalCost: calculateApiCost(this.getModel().info, totalInputTokens, totalOutputTokens), + } + } catch (error: unknown) { + this.ensureCleanState() + + if (error instanceof vscode.CancellationError) { + throw new Error("Cline : Request cancelled by user") + } + + if (error instanceof Error) { + console.error("Cline : Stream error details:", { + message: error.message, + stack: error.stack, + name: error.name, + }) + + // Return original error if it's already an Error instance + throw error + } else if (typeof error === "object" && error !== null) { + // Handle error-like objects + const errorDetails = JSON.stringify(error, null, 2) + console.error("Cline : Stream error object:", errorDetails) + throw new Error(`Cline : Response stream error: ${errorDetails}`) + } else { + // Fallback for unknown error types + const errorMessage = String(error) + console.error("Cline : Unknown stream error:", errorMessage) + throw new Error(`Cline : Response stream error: ${errorMessage}`) + } + } + } + + // Return model information based on the current client state + getModel(): { id: string; info: ModelInfo } { + if (this.client) { + // Validate client properties + const requiredProps = { + id: this.client.id, + vendor: this.client.vendor, + family: this.client.family, + version: this.client.version, + maxInputTokens: this.client.maxInputTokens, + } + + // Log any missing properties for debugging + for (const [prop, value] of Object.entries(requiredProps)) { + if (!value && value !== 0) { + console.warn(`Cline : Client missing ${prop} property`) + } + } + + // Construct model ID using available information + const modelParts = [this.client.vendor, this.client.family, this.client.version].filter(Boolean) + + const modelId = this.client.id || modelParts.join(SELECTOR_SEPARATOR) + + // Build model info with conservative defaults for missing values + const modelInfo: ModelInfo = { + maxTokens: -1, // Unlimited tokens by default + contextWindow: + typeof this.client.maxInputTokens === "number" + ? Math.max(0, this.client.maxInputTokens) + : openAiModelInfoSaneDefaults.contextWindow, + supportsImages: false, // VSCode Language Model API currently doesn't support image inputs + supportsPromptCache: true, + inputPrice: 0, + outputPrice: 0, + description: `VSCode Language Model: ${modelId}`, + } + + return { id: modelId, info: modelInfo } + } + + // Fallback when no client is available + const fallbackId = this.options.vsCodeLmModelSelector + ? stringifyVsCodeLmModelSelector(this.options.vsCodeLmModelSelector) + : "vscode-lm" + + console.debug("Cline : No client available, using fallback model info") + + return { + id: fallbackId, + info: { + ...openAiModelInfoSaneDefaults, + description: `VSCode Language Model (Fallback): ${fallbackId}`, + }, + } + } + + async completePrompt(prompt: string): Promise { + try { + const client = await this.getClient() + const response = await client.sendRequest( + [vscode.LanguageModelChatMessage.User(prompt)], + {}, + new vscode.CancellationTokenSource().token, + ) + let result = "" + for await (const chunk of response.stream) { + if (chunk instanceof vscode.LanguageModelTextPart) { + result += chunk.value + } + } + return result + } catch (error) { + if (error instanceof Error) { + throw new Error(`VSCode LM completion error: ${error.message}`) + } + throw error + } + } +} diff --git a/src/api/transform/gemini-format.ts b/src/api/transform/gemini-format.ts index 935e47147a..0a783dc183 100644 --- a/src/api/transform/gemini-format.ts +++ b/src/api/transform/gemini-format.ts @@ -124,17 +124,10 @@ export function convertAnthropicToolToGemini(tool: Anthropic.Messages.Tool): Fun It looks like gemini likes to double escape certain characters when writing file contents: https://discuss.ai.google.dev/t/function-call-string-property-is-double-escaped/37867 */ export function unescapeGeminiContent(content: string) { - return content - .replace(/\\n/g, "\n") - .replace(/\\'/g, "'") - .replace(/\\"/g, '"') - .replace(/\\r/g, "\r") - .replace(/\\t/g, "\t") + return content.replace(/\\n/g, "\n").replace(/\\'/g, "'").replace(/\\"/g, '"').replace(/\\r/g, "\r").replace(/\\t/g, "\t") } -export function convertGeminiResponseToAnthropic( - response: EnhancedGenerateContentResponse, -): Anthropic.Messages.Message { +export function convertGeminiResponseToAnthropic(response: EnhancedGenerateContentResponse): Anthropic.Messages.Message { const content: Anthropic.Messages.ContentBlock[] = [] // Add the main text response diff --git a/src/api/transform/mistral-format.ts b/src/api/transform/mistral-format.ts new file mode 100644 index 0000000000..16c6aaf238 --- /dev/null +++ b/src/api/transform/mistral-format.ts @@ -0,0 +1,92 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import { Mistral } from "@mistralai/mistralai" +import { AssistantMessage } from "@mistralai/mistralai/models/components/assistantmessage" +import { SystemMessage } from "@mistralai/mistralai/models/components/systemmessage" +import { ToolMessage } from "@mistralai/mistralai/models/components/toolmessage" +import { UserMessage } from "@mistralai/mistralai/models/components/usermessage" + +export type MistralMessage = + | (SystemMessage & { role: "system" }) + | (UserMessage & { role: "user" }) + | (AssistantMessage & { role: "assistant" }) + | (ToolMessage & { role: "tool" }) + +export function convertToMistralMessages(anthropicMessages: Anthropic.Messages.MessageParam[]): MistralMessage[] { + const mistralMessages: MistralMessage[] = [] + for (const anthropicMessage of anthropicMessages) { + if (typeof anthropicMessage.content === "string") { + mistralMessages.push({ + role: anthropicMessage.role, + content: anthropicMessage.content, + }) + } else { + if (anthropicMessage.role === "user") { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolResultBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_result") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } // user cannot send tool_use messages + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + if (nonToolMessages.length > 0) { + mistralMessages.push({ + role: "user", + content: nonToolMessages.map((part) => { + if (part.type === "image") { + return { + type: "image_url", + imageUrl: { + url: `data:${part.source.media_type};base64,${part.source.data}`, + }, + } + } + return { type: "text", text: part.text } + }), + }) + } + } else if (anthropicMessage.role === "assistant") { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolUseBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_use") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } // assistant cannot send tool_result messages + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + let content: string | undefined + if (nonToolMessages.length > 0) { + content = nonToolMessages + .map((part) => { + if (part.type === "image") { + return "" // impossible as the assistant cannot send images + } + return part.text + }) + .join("\n") + } + + mistralMessages.push({ + role: "assistant", + content, + }) + } + } + } + + return mistralMessages +} diff --git a/src/api/transform/o1-format.ts b/src/api/transform/o1-format.ts index 1346fdbd54..b7577cf903 100644 --- a/src/api/transform/o1-format.ts +++ b/src/api/transform/o1-format.ts @@ -244,7 +244,10 @@ const toolNames = [ "attempt_completion", ] -function parseAIResponse(response: string): { normalText: string; toolCalls: ToolCall[] } { +function parseAIResponse(response: string): { + normalText: string + toolCalls: ToolCall[] +} { // Create a regex pattern to match any tool call opening tag const toolCallPattern = new RegExp(`<(${toolNames.join("|")})`, "i") const match = response.match(toolCallPattern) diff --git a/src/api/transform/openai-format.ts b/src/api/transform/openai-format.ts index fe23b9b2ff..0b134ad4ac 100644 --- a/src/api/transform/openai-format.ts +++ b/src/api/transform/openai-format.ts @@ -8,7 +8,10 @@ export function convertToOpenAiMessages( for (const anthropicMessage of anthropicMessages) { if (typeof anthropicMessage.content === "string") { - openAiMessages.push({ role: anthropicMessage.role, content: anthropicMessage.content }) + openAiMessages.push({ + role: anthropicMessage.role, + content: anthropicMessage.content, + }) } else { // image_url.url is base64 encoded image data // ensure it contains the content-type of the image: data:image/png;base64, @@ -85,7 +88,9 @@ export function convertToOpenAiMessages( if (part.type === "image") { return { type: "image_url", - image_url: { url: `data:${part.source.media_type};base64,${part.source.data}` }, + image_url: { + url: `data:${part.source.media_type};base64,${part.source.data}`, + }, } } return { type: "text", text: part.text } @@ -146,9 +151,7 @@ export function convertToOpenAiMessages( } // Convert OpenAI response to Anthropic format -export function convertToAnthropicMessage( - completion: OpenAI.Chat.Completions.ChatCompletion, -): Anthropic.Messages.Message { +export function convertToAnthropicMessage(completion: OpenAI.Chat.Completions.ChatCompletion): Anthropic.Messages.Message { const openAiMessage = completion.choices[0].message const anthropicMessage: Anthropic.Messages.Message = { id: completion.id, diff --git a/src/api/transform/r1-format.ts b/src/api/transform/r1-format.ts new file mode 100644 index 0000000000..51a4b94dbc --- /dev/null +++ b/src/api/transform/r1-format.ts @@ -0,0 +1,98 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" + +type ContentPartText = OpenAI.Chat.ChatCompletionContentPartText +type ContentPartImage = OpenAI.Chat.ChatCompletionContentPartImage +type UserMessage = OpenAI.Chat.ChatCompletionUserMessageParam +type AssistantMessage = OpenAI.Chat.ChatCompletionAssistantMessageParam +type Message = OpenAI.Chat.ChatCompletionMessageParam +type AnthropicMessage = Anthropic.Messages.MessageParam + +/** + * Converts Anthropic messages to OpenAI format while merging consecutive messages with the same role. + * This is required for DeepSeek Reasoner which does not support successive messages with the same role. + * + * @param messages Array of Anthropic messages + * @returns Array of OpenAI messages where consecutive messages with the same role are combined + */ +export function convertToR1Format(messages: AnthropicMessage[]): Message[] { + return messages.reduce((merged, message) => { + const lastMessage = merged[merged.length - 1] + let messageContent: string | (ContentPartText | ContentPartImage)[] = "" + let hasImages = false + + // Convert content to appropriate format + if (Array.isArray(message.content)) { + const textParts: string[] = [] + const imageParts: ContentPartImage[] = [] + + message.content.forEach((part) => { + if (part.type === "text") { + textParts.push(part.text) + } + if (part.type === "image") { + hasImages = true + imageParts.push({ + type: "image_url", + image_url: { url: `data:${part.source.media_type};base64,${part.source.data}` }, + }) + } + }) + + if (hasImages) { + const parts: (ContentPartText | ContentPartImage)[] = [] + if (textParts.length > 0) { + parts.push({ type: "text", text: textParts.join("\n") }) + } + parts.push(...imageParts) + messageContent = parts + } else { + messageContent = textParts.join("\n") + } + } else { + messageContent = message.content + } + + // If last message has same role, merge the content + if (lastMessage?.role === message.role) { + if (typeof lastMessage.content === "string" && typeof messageContent === "string") { + lastMessage.content += `\n${messageContent}` + } + // If either has image content, convert both to array format + else { + const lastContent = Array.isArray(lastMessage.content) + ? lastMessage.content + : [{ type: "text" as const, text: lastMessage.content || "" }] + + const newContent = Array.isArray(messageContent) + ? messageContent + : [{ type: "text" as const, text: messageContent }] + + if (message.role === "assistant") { + const mergedContent = [...lastContent, ...newContent] as AssistantMessage["content"] + lastMessage.content = mergedContent + } else { + const mergedContent = [...lastContent, ...newContent] as UserMessage["content"] + lastMessage.content = mergedContent + } + } + } else { + // Add as new message with the correct type based on role + if (message.role === "assistant") { + const newMessage: AssistantMessage = { + role: "assistant", + content: messageContent as AssistantMessage["content"], + } + merged.push(newMessage) + } else { + const newMessage: UserMessage = { + role: "user", + content: messageContent as UserMessage["content"], + } + merged.push(newMessage) + } + } + + return merged + }, []) +} diff --git a/src/api/transform/stream.ts b/src/api/transform/stream.ts index 0290201dad..712f839b49 100644 --- a/src/api/transform/stream.ts +++ b/src/api/transform/stream.ts @@ -1,11 +1,16 @@ export type ApiStream = AsyncGenerator -export type ApiStreamChunk = ApiStreamTextChunk | ApiStreamUsageChunk +export type ApiStreamChunk = ApiStreamTextChunk | ApiStreamReasoningChunk | ApiStreamUsageChunk export interface ApiStreamTextChunk { type: "text" text: string } +export interface ApiStreamReasoningChunk { + type: "reasoning" + reasoning: string +} + export interface ApiStreamUsageChunk { type: "usage" inputTokens: number diff --git a/src/api/transform/vscode-lm-format.ts b/src/api/transform/vscode-lm-format.ts new file mode 100644 index 0000000000..acec3656e1 --- /dev/null +++ b/src/api/transform/vscode-lm-format.ts @@ -0,0 +1,200 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import * as vscode from "vscode" + +/** + * Safely converts a value into a plain object. + */ +function asObjectSafe(value: any): object { + // Handle null/undefined + if (!value) { + return {} + } + + try { + // Handle strings that might be JSON + if (typeof value === "string") { + return JSON.parse(value) + } + + // Handle pre-existing objects + if (typeof value === "object") { + return Object.assign({}, value) + } + + return {} + } catch (error) { + console.warn("Cline : Failed to parse object:", error) + return {} + } +} + +export function convertToVsCodeLmMessages( + anthropicMessages: Anthropic.Messages.MessageParam[], +): vscode.LanguageModelChatMessage[] { + const vsCodeLmMessages: vscode.LanguageModelChatMessage[] = [] + + for (const anthropicMessage of anthropicMessages) { + // Handle simple string messages + if (typeof anthropicMessage.content === "string") { + vsCodeLmMessages.push( + anthropicMessage.role === "assistant" + ? vscode.LanguageModelChatMessage.Assistant(anthropicMessage.content) + : vscode.LanguageModelChatMessage.User(anthropicMessage.content), + ) + continue + } + + // Handle complex message structures + switch (anthropicMessage.role) { + case "user": { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolResultBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_result") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + // Process tool messages first then non-tool messages + const contentParts = [ + // Convert tool messages to ToolResultParts + ...toolMessages.map((toolMessage) => { + // Process tool result content into TextParts + const toolContentParts: vscode.LanguageModelTextPart[] = + typeof toolMessage.content === "string" + ? [new vscode.LanguageModelTextPart(toolMessage.content)] + : (toolMessage.content?.map((part) => { + if (part.type === "image") { + return new vscode.LanguageModelTextPart( + `[Image (${part.source?.type || "Unknown source-type"}): ${part.source?.media_type || "unknown media-type"} not supported by VSCode LM API]`, + ) + } + return new vscode.LanguageModelTextPart(part.text) + }) ?? [new vscode.LanguageModelTextPart("")]) + + return new vscode.LanguageModelToolResultPart(toolMessage.tool_use_id, toolContentParts) + }), + + // Convert non-tool messages to TextParts after tool messages + ...nonToolMessages.map((part) => { + if (part.type === "image") { + return new vscode.LanguageModelTextPart( + `[Image (${part.source?.type || "Unknown source-type"}): ${part.source?.media_type || "unknown media-type"} not supported by VSCode LM API]`, + ) + } + return new vscode.LanguageModelTextPart(part.text) + }), + ] + + // Add single user message with all content parts + vsCodeLmMessages.push(vscode.LanguageModelChatMessage.User(contentParts)) + break + } + + case "assistant": { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolUseBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_use") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + // Process tool messages first then non-tool messages + const contentParts = [ + // Convert tool messages to ToolCallParts first + ...toolMessages.map( + (toolMessage) => + new vscode.LanguageModelToolCallPart( + toolMessage.id, + toolMessage.name, + asObjectSafe(toolMessage.input), + ), + ), + + // Convert non-tool messages to TextParts after tool messages + ...nonToolMessages.map((part) => { + if (part.type === "image") { + return new vscode.LanguageModelTextPart("[Image generation not supported by VSCode LM API]") + } + return new vscode.LanguageModelTextPart(part.text) + }), + ] + + // Add the assistant message to the list of messages + vsCodeLmMessages.push(vscode.LanguageModelChatMessage.Assistant(contentParts)) + break + } + } + } + + return vsCodeLmMessages +} + +export function convertToAnthropicRole(vsCodeLmMessageRole: vscode.LanguageModelChatMessageRole): string | null { + switch (vsCodeLmMessageRole) { + case vscode.LanguageModelChatMessageRole.Assistant: + return "assistant" + case vscode.LanguageModelChatMessageRole.User: + return "user" + default: + return null + } +} + +export async function convertToAnthropicMessage( + vsCodeLmMessage: vscode.LanguageModelChatMessage, +): Promise { + const anthropicRole: string | null = convertToAnthropicRole(vsCodeLmMessage.role) + if (anthropicRole !== "assistant") { + throw new Error("Cline : Only assistant messages are supported.") + } + + return { + id: crypto.randomUUID(), + type: "message", + model: "vscode-lm", + role: anthropicRole, + content: vsCodeLmMessage.content + .map((part): Anthropic.ContentBlock | null => { + if (part instanceof vscode.LanguageModelTextPart) { + return { + type: "text", + text: part.value, + } + } + + if (part instanceof vscode.LanguageModelToolCallPart) { + return { + type: "tool_use", + id: part.callId || crypto.randomUUID(), + name: part.name, + input: asObjectSafe(part.input), + } + } + + return null + }) + .filter((part): part is Anthropic.ContentBlock => part !== null), + stop_reason: null, + stop_sequence: null, + usage: { + input_tokens: 0, + output_tokens: 0, + }, + } +} diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 3b94b02efb..6c1239cae3 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -2,16 +2,18 @@ import { Anthropic } from "@anthropic-ai/sdk" import cloneDeep from "clone-deep" import delay from "delay" import fs from "fs/promises" +import getFolderSize from "get-folder-size" import os from "os" import pWaitFor from "p-wait-for" import * as path from "path" import { serializeError } from "serialize-error" import * as vscode from "vscode" import { ApiHandler, buildApiHandler } from "../api" -import { ApiStream } from "../api/transform/stream" -import { DiffViewProvider } from "../integrations/editor/DiffViewProvider" +import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" +import { DIFF_VIEW_URI_SCHEME, DiffViewProvider } from "../integrations/editor/DiffViewProvider" import { findToolName, formatContentBlockToMarkdown } from "../integrations/misc/export-markdown" import { extractTextFromFile } from "../integrations/misc/extract-text" +import { showSystemNotification } from "../integrations/notifications" import { TerminalManager } from "../integrations/terminal/TerminalManager" import { BrowserSession } from "../services/browser/BrowserSession" import { UrlContentFetcher } from "../services/browser/UrlContentFetcher" @@ -19,8 +21,10 @@ import { listFiles } from "../services/glob/list-files" import { regexSearchFiles } from "../services/ripgrep" import { parseSourceCodeForDefinitionsTopLevel } from "../services/tree-sitter" import { ApiConfiguration } from "../shared/api" -import { findLastIndex } from "../shared/array" +import { findLast, findLastIndex } from "../shared/array" import { AutoApprovalSettings } from "../shared/AutoApprovalSettings" +import { BrowserSettings } from "../shared/BrowserSettings" +import { ChatSettings } from "../shared/ChatSettings" import { combineApiRequests } from "../shared/combineApiRequests" import { combineCommandSequences, COMMAND_REQ_APP_STRING } from "../shared/combineCommandSequences" import { @@ -35,24 +39,29 @@ import { ClineSay, ClineSayBrowserAction, ClineSayTool, + COMPLETION_RESULT_CHANGES_FLAG, } from "../shared/ExtensionMessage" import { getApiMetrics } from "../shared/getApiMetrics" import { HistoryItem } from "../shared/HistoryItem" -import { ClineAskResponse } from "../shared/WebviewMessage" +import { ClineAskResponse, ClineCheckpointRestore } from "../shared/WebviewMessage" import { calculateApiCost } from "../utils/cost" import { fileExistsAtPath } from "../utils/fs" +import { LLMFileAccessController } from "../services/llm-access-control/LLMFileAccessController" import { arePathsEqual, getReadablePath } from "../utils/path" +import { fixModelHtmlEscaping, removeInvalidChars } from "../utils/string" import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message" import { constructNewFileContent } from "./assistant-message/diff" import { parseMentions } from "./mentions" import { formatResponse } from "./prompts/responses" -import { addUserInstructions, SYSTEM_PROMPT } from "./prompts/system" -import { truncateHalfConversation } from "./sliding-window" import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider" -import { showSystemNotification } from "../integrations/notifications" +import { OpenRouterHandler } from "../api/providers/openrouter" +import { getNextTruncationRange, getTruncatedMessages } from "./sliding-window" +import { SYSTEM_PROMPT } from "./prompts/system" +import { addUserInstructions } from "./prompts/system" +import { OpenAiHandler } from "../api/providers/openai" +import { ApiStream } from "../api/transform/stream" -const cwd = - vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution +const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution type ToolResponse = string | Array type UserContent = Array< @@ -64,12 +73,15 @@ export class Cline { api: ApiHandler private terminalManager: TerminalManager private urlContentFetcher: UrlContentFetcher - private browserSession: BrowserSession + browserSession: BrowserSession private didEditFile: boolean = false customInstructions?: string autoApprovalSettings: AutoApprovalSettings + private browserSettings: BrowserSettings + private chatSettings: ChatSettings apiConversationHistory: Anthropic.MessageParam[] = [] clineMessages: ClineMessage[] = [] + private llmAccessController: LLMFileAccessController private askResponse?: ClineAskResponse private askResponseText?: string private askResponseImages?: string[] @@ -78,11 +90,19 @@ export class Cline { private consecutiveMistakeCount: number = 0 private providerRef: WeakRef private abort: boolean = false - didFinishAborting = false + didFinishAbortingStream = false abandoned = false private diffViewProvider: DiffViewProvider + private checkpointTracker?: CheckpointTracker + checkpointTrackerErrorMessage?: string + conversationHistoryDeletedRange?: [number, number] + isInitialized = false + isAwaitingPlanResponse = false + didRespondToPlanAskBySwitchingMode = false // streaming + isWaitingForFirstChunk = false + isStreaming = false private currentStreamingContentIndex = 0 private assistantMessageContent: AssistantMessageContent[] = [] private presentAssistantMessageLocked = false @@ -92,26 +112,36 @@ export class Cline { private didRejectTool = false private didAlreadyUseTool = false private didCompleteReadingStream = false + private didAutomaticallyRetryFailedApiRequest = false constructor( provider: ClineProvider, apiConfiguration: ApiConfiguration, autoApprovalSettings: AutoApprovalSettings, + browserSettings: BrowserSettings, + chatSettings: ChatSettings, customInstructions?: string, task?: string, images?: string[], historyItem?: HistoryItem, ) { + this.llmAccessController = new LLMFileAccessController(cwd) + this.llmAccessController.initialize().catch((error) => { + console.error("Failed to initialize LLMFileAccessController:", error) + }) this.providerRef = new WeakRef(provider) this.api = buildApiHandler(apiConfiguration) this.terminalManager = new TerminalManager() this.urlContentFetcher = new UrlContentFetcher(provider.context) - this.browserSession = new BrowserSession(provider.context) + this.browserSession = new BrowserSession(provider.context, browserSettings) this.diffViewProvider = new DiffViewProvider(cwd) this.customInstructions = customInstructions this.autoApprovalSettings = autoApprovalSettings + this.browserSettings = browserSettings + this.chatSettings = chatSettings if (historyItem) { this.taskId = historyItem.id + this.conversationHistoryDeletedRange = historyItem.conversationHistoryDeletedRange this.resumeTaskFromHistory() } else if (task || images) { this.taskId = Date.now().toString() @@ -121,6 +151,15 @@ export class Cline { } } + updateBrowserSettings(browserSettings: BrowserSettings) { + this.browserSettings = browserSettings + this.browserSession.browserSettings = browserSettings + } + + updateChatSettings(chatSettings: ChatSettings) { + this.chatSettings = chatSettings + } + // Storing task to disk for history private async ensureTaskDirectoryExists(): Promise { @@ -179,6 +218,10 @@ export class Cline { } private async addToClineMessages(message: ClineMessage) { + // these values allow us to reconstruct the conversation history at the time this cline message was created + // it's important that apiConversationHistory is initialized before we add cline messages + message.conversationHistoryIndex = this.apiConversationHistory.length - 1 // NOTE: this is the index of the last added message which is the user message, and once the clinemessages have been presented we update the apiconversationhistory with the completed assistant message. This means when resetting to a message, we need to +1 this index to get the correct assistant message that this tool use corresponds to + message.conversationHistoryDeletedRange = this.conversationHistoryDeletedRange this.clineMessages.push(message) await this.saveClineMessages() } @@ -190,18 +233,24 @@ export class Cline { private async saveClineMessages() { try { - const filePath = path.join(await this.ensureTaskDirectoryExists(), GlobalFileNames.uiMessages) + const taskDir = await this.ensureTaskDirectoryExists() + const filePath = path.join(taskDir, GlobalFileNames.uiMessages) await fs.writeFile(filePath, JSON.stringify(this.clineMessages)) // combined as they are in ChatView const apiMetrics = getApiMetrics(combineApiRequests(combineCommandSequences(this.clineMessages.slice(1)))) const taskMessage = this.clineMessages[0] // first message is always the task say const lastRelevantMessage = this.clineMessages[ - findLastIndex( - this.clineMessages, - (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"), - ) + findLastIndex(this.clineMessages, (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task")) ] + let taskDirSize = 0 + try { + // getFolderSize.loose silently ignores errors + // returns # of bytes, size/1000/1000 = MB + taskDirSize = await getFolderSize.loose(taskDir) + } catch (error) { + console.error("Failed to get task directory size:", taskDir, error) + } await this.providerRef.deref()?.updateTaskHistory({ id: this.taskId, ts: lastRelevantMessage.ts, @@ -211,12 +260,265 @@ export class Cline { cacheWrites: apiMetrics.totalCacheWrites, cacheReads: apiMetrics.totalCacheReads, totalCost: apiMetrics.totalCost, + size: taskDirSize, + shadowGitConfigWorkTree: await this.checkpointTracker?.getShadowGitConfigWorkTree(), + conversationHistoryDeletedRange: this.conversationHistoryDeletedRange, }) } catch (error) { console.error("Failed to save cline messages:", error) } } + async restoreCheckpoint(messageTs: number, restoreType: ClineCheckpointRestore) { + const messageIndex = this.clineMessages.findIndex((m) => m.ts === messageTs) + const message = this.clineMessages[messageIndex] + if (!message) { + console.error("Message not found", this.clineMessages) + return + } + + let didWorkspaceRestoreFail = false + + switch (restoreType) { + case "task": + break + case "taskAndWorkspace": + case "workspace": + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref()) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + console.error("Failed to initialize checkpoint tracker:", errorMessage) + this.checkpointTrackerErrorMessage = errorMessage + await this.providerRef.deref()?.postStateToWebview() + vscode.window.showErrorMessage(errorMessage) + didWorkspaceRestoreFail = true + } + } + if (message.lastCheckpointHash && this.checkpointTracker) { + try { + await this.checkpointTracker.resetHead(message.lastCheckpointHash) + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + vscode.window.showErrorMessage("Failed to restore checkpoint: " + errorMessage) + didWorkspaceRestoreFail = true + } + } + break + } + + if (!didWorkspaceRestoreFail) { + switch (restoreType) { + case "task": + case "taskAndWorkspace": + this.conversationHistoryDeletedRange = message.conversationHistoryDeletedRange + const newConversationHistory = this.apiConversationHistory.slice( + 0, + (message.conversationHistoryIndex || 0) + 2, + ) // +1 since this index corresponds to the last user message, and another +1 since slice end index is exclusive + await this.overwriteApiConversationHistory(newConversationHistory) + + // aggregate deleted api reqs info so we don't lose costs/tokens + const deletedMessages = this.clineMessages.slice(messageIndex + 1) + const deletedApiReqsMetrics = getApiMetrics(combineApiRequests(combineCommandSequences(deletedMessages))) + + const newClineMessages = this.clineMessages.slice(0, messageIndex + 1) + await this.overwriteClineMessages(newClineMessages) // calls saveClineMessages which saves historyItem + + await this.say( + "deleted_api_reqs", + JSON.stringify({ + tokensIn: deletedApiReqsMetrics.totalTokensIn, + tokensOut: deletedApiReqsMetrics.totalTokensOut, + cacheWrites: deletedApiReqsMetrics.totalCacheWrites, + cacheReads: deletedApiReqsMetrics.totalCacheReads, + cost: deletedApiReqsMetrics.totalCost, + } satisfies ClineApiReqInfo), + ) + break + case "workspace": + break + } + + switch (restoreType) { + case "task": + vscode.window.showInformationMessage("Task messages have been restored to the checkpoint") + break + case "workspace": + vscode.window.showInformationMessage("Workspace files have been restored to the checkpoint") + break + case "taskAndWorkspace": + vscode.window.showInformationMessage("Task and workspace have been restored to the checkpoint") + break + } + + await this.providerRef.deref()?.postMessageToWebview({ type: "relinquishControl" }) + + this.providerRef.deref()?.cancelTask() // the task is already cancelled by the provider beforehand, but we need to re-init to get the updated messages + } else { + await this.providerRef.deref()?.postMessageToWebview({ type: "relinquishControl" }) + } + } + + async presentMultifileDiff(messageTs: number, seeNewChangesSinceLastTaskCompletion: boolean) { + const relinquishButton = () => { + this.providerRef.deref()?.postMessageToWebview({ type: "relinquishControl" }) + } + + console.log("presentMultifileDiff", messageTs) + const messageIndex = this.clineMessages.findIndex((m) => m.ts === messageTs) + const message = this.clineMessages[messageIndex] + if (!message) { + console.error("Message not found") + relinquishButton() + return + } + const hash = message.lastCheckpointHash + if (!hash) { + console.error("No checkpoint hash found") + relinquishButton() + return + } + + // TODO: handle if this is called from outside original workspace, in which case we need to show user error message we cant show diff outside of workspace? + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref()) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + console.error("Failed to initialize checkpoint tracker:", errorMessage) + this.checkpointTrackerErrorMessage = errorMessage + await this.providerRef.deref()?.postStateToWebview() + vscode.window.showErrorMessage(errorMessage) + relinquishButton() + return + } + } + + let changedFiles: + | { + relativePath: string + absolutePath: string + before: string + after: string + }[] + | undefined + + try { + if (seeNewChangesSinceLastTaskCompletion) { + // Get last task completed + const lastTaskCompletedMessage = findLast( + this.clineMessages.slice(0, messageIndex), + (m) => m.say === "completion_result", + ) // ask is only used to relinquish control, its the last say we care about + // if undefined, then we get diff from beginning of git + // if (!lastTaskCompletedMessage) { + // console.error("No previous task completion message found") + // return + // } + + // Get changed files between current state and commit + changedFiles = await this.checkpointTracker?.getDiffSet( + lastTaskCompletedMessage?.lastCheckpointHash, // if undefined, then we get diff from beginning of git history, AKA when the task was started + hash, + ) + if (!changedFiles?.length) { + vscode.window.showInformationMessage("No changes found") + relinquishButton() + return + } + } else { + // Get changed files between current state and commit + changedFiles = await this.checkpointTracker?.getDiffSet(hash) + if (!changedFiles?.length) { + vscode.window.showInformationMessage("No changes found") + relinquishButton() + return + } + } + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + vscode.window.showErrorMessage("Failed to retrieve diff set: " + errorMessage) + relinquishButton() + return + } + + // Check if multi-diff editor is enabled in VS Code settings + // const config = vscode.workspace.getConfiguration() + // const isMultiDiffEnabled = config.get("multiDiffEditor.experimental.enabled") + + // if (!isMultiDiffEnabled) { + // vscode.window.showErrorMessage( + // "Please enable 'multiDiffEditor.experimental.enabled' in your VS Code settings to use this feature.", + // ) + // relinquishButton() + // return + // } + // Open multi-diff editor + await vscode.commands.executeCommand( + "vscode.changes", + seeNewChangesSinceLastTaskCompletion ? "New changes" : "Changes since snapshot", + changedFiles.map((file) => [ + vscode.Uri.file(file.absolutePath), + vscode.Uri.parse(`${DIFF_VIEW_URI_SCHEME}:${file.relativePath}`).with({ + query: Buffer.from(file.before ?? "").toString("base64"), + }), + vscode.Uri.parse(`${DIFF_VIEW_URI_SCHEME}:${file.relativePath}`).with({ + query: Buffer.from(file.after ?? "").toString("base64"), + }), + ]), + ) + relinquishButton() + } + + async doesLatestTaskCompletionHaveNewChanges() { + const messageIndex = findLastIndex(this.clineMessages, (m) => m.say === "completion_result") + const message = this.clineMessages[messageIndex] + if (!message) { + console.error("Completion message not found") + return false + } + const hash = message.lastCheckpointHash + if (!hash) { + console.error("No checkpoint hash found") + return false + } + + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref()) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + console.error("Failed to initialize checkpoint tracker:", errorMessage) + return false + } + } + + // Get last task completed + const lastTaskCompletedMessage = findLast(this.clineMessages.slice(0, messageIndex), (m) => m.say === "completion_result") + + try { + // Get changed files between current state and commit + const changedFiles = await this.checkpointTracker?.getDiffSet( + lastTaskCompletedMessage?.lastCheckpointHash, // if undefined, then we get diff from beginning of git history, AKA when the task was started + hash, + ) + const changedFilesCount = changedFiles?.length || 0 + if (changedFilesCount > 0) { + return true + } + } catch (error) { + console.error("Failed to get diff set:", error) + return false + } + + return false + } + // Communicate with webview // partial has three valid states true (partial message), false (completion of partial message), undefined (individual complete message) @@ -224,7 +526,11 @@ export class Cline { type: ClineAsk, text?: string, partial?: boolean, - ): Promise<{ response: ClineAskResponse; text?: string; images?: string[] }> { + ): Promise<{ + response: ClineAskResponse + text?: string + images?: string[] + }> { // If this Cline instance was aborted by the provider, then the only thing keeping us alive is a promise still running in the background, in which case we don't want to send its result to the webview as it is attached to a new instance of Cline now. So we can safely ignore the result of any active promises, and this class will be deallocated. (Although we set Cline = undefined in provider, that simply removes the reference to this instance, but the instance is still alive until this promise resolves or rejects.) if (this.abort) { throw new Error("Cline instance aborted") @@ -242,9 +548,10 @@ export class Cline { // todo be more efficient about saving and posting only new data or one whole message at a time so ignore partial for saves, and only post parts of partial message instead of whole array in new listener // await this.saveClineMessages() // await this.providerRef.deref()?.postStateToWebview() - await this.providerRef - .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) + await this.providerRef.deref()?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) throw new Error("Current ask promise was ignored 1") } else { // this is a new partial message, so add it with partial state @@ -253,7 +560,13 @@ export class Cline { // this.askResponseImages = undefined askTs = Date.now() this.lastMessageTs = askTs - await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text, partial }) + await this.addToClineMessages({ + ts: askTs, + type: "ask", + ask: type, + text, + partial, + }) await this.providerRef.deref()?.postStateToWebview() throw new Error("Current ask promise was ignored 2") } @@ -278,9 +591,10 @@ export class Cline { lastMessage.partial = false await this.saveClineMessages() // await this.providerRef.deref()?.postStateToWebview() - await this.providerRef - .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) + await this.providerRef.deref()?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) } else { // this is a new partial=false message, so add it like normal this.askResponse = undefined @@ -288,7 +602,12 @@ export class Cline { this.askResponseImages = undefined askTs = Date.now() this.lastMessageTs = askTs - await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text }) + await this.addToClineMessages({ + ts: askTs, + type: "ask", + ask: type, + text, + }) await this.providerRef.deref()?.postStateToWebview() } } @@ -300,7 +619,12 @@ export class Cline { this.askResponseImages = undefined askTs = Date.now() this.lastMessageTs = askTs - await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text }) + await this.addToClineMessages({ + ts: askTs, + type: "ask", + ask: type, + text, + }) await this.providerRef.deref()?.postStateToWebview() } @@ -308,7 +632,11 @@ export class Cline { if (this.lastMessageTs !== askTs) { throw new Error("Current ask promise was ignored") // could happen if we send multiple asks in a row i.e. with command_output. It's important that when we know an ask could fail, it is handled gracefully } - const result = { response: this.askResponse!, text: this.askResponseText, images: this.askResponseImages } + const result = { + response: this.askResponse!, + text: this.askResponseText, + images: this.askResponseImages, + } this.askResponse = undefined this.askResponseText = undefined this.askResponseImages = undefined @@ -336,14 +664,22 @@ export class Cline { lastMessage.text = text lastMessage.images = images lastMessage.partial = partial - await this.providerRef - .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) + await this.providerRef.deref()?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) } else { // this is a new partial message, so add it with partial state const sayTs = Date.now() this.lastMessageTs = sayTs - await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images, partial }) + await this.addToClineMessages({ + ts: sayTs, + type: "say", + say: type, + text, + images, + partial, + }) await this.providerRef.deref()?.postStateToWebview() } } else { @@ -359,14 +695,21 @@ export class Cline { // instead of streaming partialMessage events, we do a save and post like normal to persist to disk await this.saveClineMessages() // await this.providerRef.deref()?.postStateToWebview() - await this.providerRef - .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) // more performant than an entire postStateToWebview + await this.providerRef.deref()?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) // more performant than an entire postStateToWebview } else { // this is a new partial=false message, so add it like normal const sayTs = Date.now() this.lastMessageTs = sayTs - await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images }) + await this.addToClineMessages({ + ts: sayTs, + type: "say", + say: type, + text, + images, + }) await this.providerRef.deref()?.postStateToWebview() } } @@ -374,7 +717,13 @@ export class Cline { // this is a new non-partial message, so add it like normal const sayTs = Date.now() this.lastMessageTs = sayTs - await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images }) + await this.addToClineMessages({ + ts: sayTs, + type: "say", + say: type, + text, + images, + }) await this.providerRef.deref()?.postStateToWebview() } } @@ -391,11 +740,7 @@ export class Cline { async removeLastPartialMessageIfExistsWithType(type: "ask" | "say", askOrSay: ClineAsk | ClineSay) { const lastMessage = this.clineMessages.at(-1) - if ( - lastMessage?.partial && - lastMessage.type === type && - (lastMessage.ask === askOrSay || lastMessage.say === askOrSay) - ) { + if (lastMessage?.partial && lastMessage.type === type && (lastMessage.ask === askOrSay || lastMessage.say === askOrSay)) { this.clineMessages.pop() await this.saveClineMessages() await this.providerRef.deref()?.postStateToWebview() @@ -409,21 +754,33 @@ export class Cline { // if the extension process were killed, then on restart the clineMessages might not be empty, so we need to set it to [] when we create a new Cline client (otherwise webview would show stale messages from previous session) this.clineMessages = [] this.apiConversationHistory = [] + await this.providerRef.deref()?.postStateToWebview() await this.say("text", task, images) + this.isInitialized = true + let imageBlocks: Anthropic.ImageBlockParam[] = formatResponse.imageBlocks(images) - await this.initiateTaskLoop([ - { - type: "text", - text: `\n${task}\n`, - }, - ...imageBlocks, - ]) + await this.initiateTaskLoop( + [ + { + type: "text", + text: `\n${task}\n`, + }, + ...imageBlocks, + ], + true, + ) } private async resumeTaskFromHistory() { + // TODO: right now we let users init checkpoints for old tasks, assuming they're continuing them from the same workspace (which we never tied to tasks, so no way for us to know if it's opened in the right workspace) + // const doesShadowGitExist = await CheckpointTracker.doesShadowGitExist(this.taskId, this.providerRef.deref()) + // if (!doesShadowGitExist) { + // this.checkpointTrackerErrorMessage = "Checkpoints are only available for new tasks" + // } + const modifiedClineMessages = await this.getSavedClineMessages() // Remove any resume messages that may have been added before @@ -451,7 +808,9 @@ export class Cline { await this.overwriteClineMessages(modifiedClineMessages) this.clineMessages = await this.getSavedClineMessages() - // Now present the cline messages to the user and ask if they want to resume + // Now present the cline messages to the user and ask if they want to resume (NOTE: we ran into a bug before where the apiconversationhistory wouldnt be initialized when opening a old task, and it was because we were waiting for resume) + // This is important in case the user deletes messages without resuming the task first + this.apiConversationHistory = await this.getSavedApiConversationHistory() const lastClineMessage = this.clineMessages .slice() @@ -475,6 +834,8 @@ export class Cline { askType = "resume_task" } + this.isInitialized = true + const { response, text, images } = await this.ask(askType) // calls poststatetowebview let responseText: string | undefined let responseImages: string[] | undefined @@ -486,8 +847,7 @@ export class Cline { // need to make sure that the api conversation history can be resumed by the api, even if it goes out of sync with cline messages - let existingApiConversationHistory: Anthropic.Messages.MessageParam[] = - await this.getSavedApiConversationHistory() + let existingApiConversationHistory: Anthropic.Messages.MessageParam[] = await this.getSavedApiConversationHistory() // v2.0 xml tags refactor caveat: since we don't use tools anymore, we need to replace all tool use blocks with a text block since the API disallows conversations with tool uses and no tool schema const conversationWithoutToolBlocks = existingApiConversationHistory.map((message) => { @@ -566,7 +926,12 @@ export class Cline { if (previousAssistantMessage && previousAssistantMessage.role === "assistant") { const assistantContent = Array.isArray(previousAssistantMessage.content) ? previousAssistantMessage.content - : [{ type: "text", text: previousAssistantMessage.content }] + : [ + { + type: "text", + text: previousAssistantMessage.content, + }, + ] const toolUseBlocks = assistantContent.filter( (block) => block.type === "tool_use", @@ -578,9 +943,7 @@ export class Cline { ) as Anthropic.ToolResultBlockParam[] const missingToolResponses: Anthropic.ToolResultBlockParam[] = toolUseBlocks - .filter( - (toolUse) => !existingToolResults.some((result) => result.tool_use_id === toolUse.id), - ) + .filter((toolUse) => !existingToolResults.some((result) => result.tool_use_id === toolUse.id)) .map((toolUse) => ({ type: "tool_result", tool_use_id: toolUse.id, @@ -602,6 +965,9 @@ export class Cline { } } else { throw new Error("Unexpected: No existing API conversation history") + // console.error("Unexpected: No existing API conversation history") + // modifiedApiConversationHistory = [] + // modifiedOldUserContent = [] } let newUserContent: UserContent = [...modifiedOldUserContent] @@ -631,14 +997,20 @@ export class Cline { newUserContent.push({ type: "text", text: - `[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.${ + `[TASK RESUMPTION] ${ + this.chatSettings?.mode === "plan" + ? `This task was interrupted ${agoText}. The conversation may have been incomplete. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful. However you are in PLAN MODE, so rather than continuing the task, you must respond to the user's message.` + : `This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.` + }${ wasRecent ? "\n\nIMPORTANT: If the last tool use was a replace_in_file or write_to_file that was interrupted, the file was reverted back to its original state before the interrupted edit, and you do NOT need to re-read the file as you already have its up-to-date contents." : "" }` + (responseText - ? `\n\nNew instructions for task continuation:\n\n${responseText}\n` - : ""), + ? `\n\n${this.chatSettings?.mode === "plan" ? "New message to respond to with plan_mode_response tool (be sure to provide your response in the parameter)" : "New instructions for task continuation"}:\n\n${responseText}\n` + : this.chatSettings.mode === "plan" + ? "(The user did not provide a new message. Consider asking them how they'd like you to proceed, or to switch to Act mode to continue with the task.)" + : ""), }) if (responseImages && responseImages.length > 0) { @@ -646,14 +1018,14 @@ export class Cline { } await this.overwriteApiConversationHistory(modifiedApiConversationHistory) - await this.initiateTaskLoop(newUserContent) + await this.initiateTaskLoop(newUserContent, false) } - private async initiateTaskLoop(userContent: UserContent): Promise { + private async initiateTaskLoop(userContent: UserContent, isNewTask: boolean): Promise { let nextUserContent = userContent let includeFileDetails = true while (!this.abort) { - const didEndLoop = await this.recursivelyMakeClineRequests(nextUserContent, includeFileDetails) + const didEndLoop = await this.recursivelyMakeClineRequests(nextUserContent, includeFileDetails, isNewTask) includeFileDetails = false // we only need file details the first time // The way this agentic loop works is that cline will be given a task that he then calls tools to complete. unless there's an attempt_completion call, we keep responding back to him with his tool's responses until he either attempt_completion or does not use anymore tools. If he does not use anymore tools, we ask him to consider if he's completed the task and then call attempt_completion, otherwise proceed with completing the task. @@ -680,12 +1052,52 @@ export class Cline { } } - abortTask() { + async abortTask() { this.abort = true // will stop any autonomously running promises this.terminalManager.disposeAll() this.urlContentFetcher.closeBrowser() this.browserSession.closeBrowser() - this.diffViewProvider.revertChanges() + this.llmAccessController.dispose() + await this.diffViewProvider.revertChanges() // need to await for when we want to make sure directories/files are reverted before re-starting the task from a checkpoint + } + + // Checkpoints + + async saveCheckpoint() { + const commitHash = await this.checkpointTracker?.commit() // silently fails for now + if (commitHash) { + // Start from the end and work backwards until we find a tool use or another message with a hash + for (let i = this.clineMessages.length - 1; i >= 0; i--) { + const message = this.clineMessages[i] + if (message.lastCheckpointHash) { + // Found a message with a hash, so we can stop + break + } + // Update this message with a hash + message.lastCheckpointHash = commitHash + + // We only care about adding the hash to the last tool use (we don't want to add this hash to every prior message ie for tasks pre-checkpoint) + const isToolUse = + message.say === "tool" || + message.ask === "tool" || + message.say === "command" || + message.ask === "command" || + message.say === "completion_result" || + message.ask === "completion_result" || + message.ask === "followup" || + message.say === "use_mcp_server" || + message.ask === "use_mcp_server" || + message.say === "browser_action" || + message.say === "browser_action_launch" || + message.ask === "browser_action_launch" + + if (isToolUse) { + break + } + } + // Save the updated messages + await this.saveClineMessages() + } } // Tools @@ -790,6 +1202,14 @@ export class Cline { return false } + private formatErrorWithStatusCode(error: any): string { + const statusCode = error.status || error.statusCode || (error.response && error.response.status) + const message = error.message ?? JSON.stringify(serializeError(error), null, 2) + + // Only prepend the statusCode if it's not already part of the message + return statusCode && !message.includes(statusCode.toString()) ? `${statusCode} - ${message}` : message + } + async *attemptApiRequest(previousApiReqIndex: number): ApiStream { // Wait for MCP servers to be connected before generating system prompt await pWaitFor(() => this.providerRef.deref()?.mcpHub?.isConnecting !== true, { timeout: 10_000 }).catch(() => { @@ -801,7 +1221,13 @@ export class Cline { throw new Error("MCP hub not available") } - let systemPrompt = await SYSTEM_PROMPT(cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub) + let systemPrompt = await SYSTEM_PROMPT( + cwd, + this.api.getModel().info.supportsComputerUse ?? false, + mcpHub, + this.browserSettings, + ) + let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined @@ -825,37 +1251,81 @@ export class Cline { if (previousApiReqIndex >= 0) { const previousRequest = this.clineMessages[previousApiReqIndex] if (previousRequest && previousRequest.text) { - const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse( - previousRequest.text, - ) + const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse(previousRequest.text) const totalTokens = (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0) - const contextWindow = this.api.getModel().info.contextWindow || 128_000 - const maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) + let contextWindow = this.api.getModel().info.contextWindow || 128_000 + // FIXME: hack to get anyone using openai compatible with deepseek to have the proper context window instead of the default 128k. We need a way for the user to specify the context window for models they input through openai compatible + if (this.api instanceof OpenAiHandler && this.api.getModel().id.toLowerCase().includes("deepseek")) { + contextWindow = 64_000 + } + let maxAllowedSize: number + switch (contextWindow) { + case 64_000: // deepseek models + maxAllowedSize = contextWindow - 27_000 + break + case 128_000: // most models + maxAllowedSize = contextWindow - 30_000 + break + case 200_000: // claude models + maxAllowedSize = contextWindow - 40_000 + break + default: + maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) // for deepseek, 80% of 64k meant only ~10k buffer which was too small and resulted in users getting context window errors. + } + + // This is the most reliable way to know when we're close to hitting the context window. if (totalTokens >= maxAllowedSize) { - const truncatedMessages = truncateHalfConversation(this.apiConversationHistory) - await this.overwriteApiConversationHistory(truncatedMessages) + // Since the user may switch between models with different context windows, truncating half may not be enough (ie if switching from claude 200k to deepseek 64k, half truncation will only remove 100k tokens, but we need to remove much more) + // So if totalTokens/2 is greater than maxAllowedSize, we truncate 3/4 instead of 1/2 + // FIXME: truncating the conversation in a way that is optimal for prompt caching AND takes into account multi-context window complexity is something we need to improve + const keep = totalTokens / 2 > maxAllowedSize ? "quarter" : "half" + + // NOTE: it's okay that we overwriteConversationHistory in resume task since we're only ever removing the last user message and not anything in the middle which would affect this range + this.conversationHistoryDeletedRange = getNextTruncationRange( + this.apiConversationHistory, + this.conversationHistoryDeletedRange, + keep, + ) + await this.saveClineMessages() // saves task history item which we use to keep track of conversation history deleted range + // await this.overwriteApiConversationHistory(truncatedMessages) } } } - const stream = this.api.createMessage(systemPrompt, this.apiConversationHistory) + // conversationHistoryDeletedRange is updated only when we're close to hitting the context window, so we don't continuously break the prompt cache + const truncatedConversationHistory = getTruncatedMessages( + this.apiConversationHistory, + this.conversationHistoryDeletedRange, + ) + + let stream = this.api.createMessage(systemPrompt, truncatedConversationHistory) + const iterator = stream[Symbol.asyncIterator]() try { // awaiting first chunk to see if it will throw an error + this.isWaitingForFirstChunk = true const firstChunk = await iterator.next() yield firstChunk.value + this.isWaitingForFirstChunk = false } catch (error) { - // note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely. - const { response } = await this.ask( - "api_req_failed", - error.message ?? JSON.stringify(serializeError(error), null, 2), - ) - if (response !== "yesButtonClicked") { - // this will never happen since if noButtonClicked, we will clear current task, aborting this instance - throw new Error("API request failed") + const isOpenRouter = this.api instanceof OpenRouterHandler + if (isOpenRouter && !this.didAutomaticallyRetryFailedApiRequest) { + console.log("first chunk failed, waiting 1 second before retrying") + await delay(1000) + this.didAutomaticallyRetryFailedApiRequest = true + } else { + // request failed after retrying automatically once, ask user if they want to retry again + // note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely. + const errorMessage = this.formatErrorWithStatusCode(error) + + const { response } = await this.ask("api_req_failed", errorMessage) + if (response !== "yesButtonClicked") { + // this will never happen since if noButtonClicked, we will clear current task, aborting this instance + throw new Error("API request failed") + } + await this.say("api_req_retried") } - await this.say("api_req_retried") // delegate generator output from the recursive call yield* this.attemptApiRequest(previousApiReqIndex) return @@ -937,7 +1407,7 @@ export class Cline { if (!block.partial) { // Some models add code block artifacts (around the tool calls) which show up at the end of text content - // matches ``` with atleast one char after the last backtick, at the end of the string + // matches ``` with at least one char after the last backtick, at the end of the string const match = content?.trimEnd().match(/```[a-zA-Z0-9_-]+$/) if (match) { const matchLength = match[0].length @@ -975,6 +1445,8 @@ export class Cline { return `[${block.name} for '${block.params.server_name}']` case "ask_followup_question": return `[${block.name} for '${block.params.question}']` + case "plan_mode_response": + return `[${block.name}]` case "attempt_completion": return `[${block.name}]` } @@ -1028,9 +1500,7 @@ export class Cline { if (response !== "yesButtonClicked") { if (response === "messageResponse") { await this.say("user_feedback", text, images) - pushToolResult( - formatResponse.toolResult(formatResponse.toolDeniedWithFeedback(text), images), - ) + pushToolResult(formatResponse.toolResult(formatResponse.toolDeniedWithFeedback(text), images)) // this.userMessageContent.push({ // type: "text", // text: `${toolDescription()}`, @@ -1068,6 +1538,10 @@ export class Cline { } const handleError = async (action: string, error: Error) => { + if (this.abandoned) { + console.log("Ignoring error since task was abandoned (i.e. from task cancellation after resetting)") + return + } const errorString = `Error ${action}: ${JSON.stringify(serializeError(error))}` await this.say( "error", @@ -1131,6 +1605,18 @@ export class Cline { // Construct newContent from diff let newContent: string if (diff) { + if (!this.api.getModel().id.includes("claude")) { + // deepseek models tend to use unescaped html entities in diffs + diff = fixModelHtmlEscaping(diff) + diff = removeInvalidChars(diff) + } + + // open the editor if not done already. This is to fix diff error when model provides correct search-replace text but Cline throws error + // because file is not open. + if (!this.diffViewProvider.isEditing) { + await this.diffViewProvider.open(relPath) + } + try { newContent = await constructNewFileContent( diff, @@ -1142,7 +1628,7 @@ export class Cline { pushToolResult( formatResponse.toolError( `${(error as Error)?.message}\n\n` + - `This is likely because the SEARCH block content doesn't match exactly with what's in the file.\n\n` + + `This is likely because the SEARCH block content doesn't match exactly with what's in the file, or if you used multiple SEARCH/REPLACE blocks they may not have been in the order they appear in the file.\n\n` + `The file was reverted to its original state:\n\n` + `\n${this.diffViewProvider.originalContent}\n\n\n` + `Try again with a more precise SEARCH block.\n(If you keep running into this error, you may use the write_to_file tool as a workaround.)`, @@ -1163,25 +1649,17 @@ export class Cline { if (newContent.endsWith("```")) { newContent = newContent.split("\n").slice(0, -1).join("\n").trim() } + + if (!this.api.getModel().id.includes("claude")) { + // it seems not just llama models are doing this, but also gemini and potentially others + newContent = fixModelHtmlEscaping(newContent) + newContent = removeInvalidChars(newContent) + } } else { // can't happen, since we already checked for content/diff above. but need to do this for type error break } - if (!this.api.getModel().id.includes("claude")) { - // it seems not just llama models are doing this, but also gemini and potentially others - if ( - newContent.includes(">") || - newContent.includes("<") || - newContent.includes(""") - ) { - newContent = newContent - .replace(/>/g, ">") - .replace(/</g, "<") - .replace(/"/g, '"') - } - } - newContent = newContent.trimEnd() // remove any trailing newlines, since it's automatically inserted by the editor const sharedMessageProps: ClineSayTool = { @@ -1213,18 +1691,21 @@ export class Cline { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError(block.name, "path")) await this.diffViewProvider.reset() + await this.saveCheckpoint() break } if (block.name === "replace_in_file" && !diff) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("replace_in_file", "diff")) await this.diffViewProvider.reset() + await this.saveCheckpoint() break } if (block.name === "write_to_file" && !content) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "content")) await this.diffViewProvider.reset() + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1267,14 +1748,41 @@ export class Cline { `Cline wants to ${fileExists ? "edit" : "create"} ${path.basename(relPath)}`, ) this.removeLastPartialMessageIfExistsWithType("say", "tool") - const didApprove = await askApproval("tool", completeMessage) + // const didApprove = await askApproval("tool", completeMessage) + + // Need a more customized tool response for file edits to highlight the fact that the file was not updated (particularly important for deepseek) + let didApprove = true + const { response, text, images } = await this.ask("tool", completeMessage, false) + if (response !== "yesButtonClicked") { + // TODO: add similar context for other tool denial responses, to emphasize ie that a command was not run + const fileDeniedNote = fileExists + ? "The file was not updated, and maintains its original contents." + : "The file was not created." + if (response === "messageResponse") { + await this.say("user_feedback", text, images) + pushToolResult( + formatResponse.toolResult( + `The user denied this operation. ${fileDeniedNote}\nThe user provided the following feedback:\n\n${text}\n`, + images, + ), + ) + this.didRejectTool = true + didApprove = false + } else { + pushToolResult(`The user denied this operation. ${fileDeniedNote}`) + this.didRejectTool = true + didApprove = false + } + } + if (!didApprove) { await this.diffViewProvider.revertChanges() + await this.saveCheckpoint() break } } - const { newProblemsMessage, userEdits, finalContent } = + const { newProblemsMessage, userEdits, autoFormattingEdits, finalContent } = await this.diffViewProvider.saveChanges() this.didEditFile = true // used to determine if we should wait for busy terminal to update before sending api request if (userEdits) { @@ -1288,31 +1796,39 @@ export class Cline { ) pushToolResult( `The user made the following updates to your content:\n\n${userEdits}\n\n` + - `The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file:\n\n` + + (autoFormattingEdits + ? `The user's editor also applied the following auto-formatting to your content:\n\n${autoFormattingEdits}\n\n(Note: Pay close attention to changes such as single quotes being converted to double quotes, semicolons being removed or added, long lines being broken into multiple lines, adjusting indentation style, adding/removing trailing commas, etc. This will help you ensure future SEARCH/REPLACE operations to this file are accurate.)\n\n` + : "") + + `The updated content, which includes both your original modifications and the additional edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file that was saved:\n\n` + `\n${finalContent}\n\n\n` + `Please note:\n` + `1. You do not need to re-write the file with these changes, as they have already been applied.\n` + `2. Proceed with the task using this updated file content as the new baseline.\n` + `3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` + - `4. If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including the user's edits and any auto-formatting done by the system).\n` + + `4. IMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference. This content reflects the current state of the file, including both user edits and any auto-formatting (e.g., if you used single quotes but the formatter converted them to double quotes). Always base your SEARCH/REPLACE operations on this final version to ensure accuracy.\n` + `${newProblemsMessage}`, ) } else { pushToolResult( `The content was successfully saved to ${relPath.toPosix()}.\n\n` + - `Here is the full, updated content of the file:\n\n` + + (autoFormattingEdits + ? `Along with your edits, the user's editor applied the following auto-formatting to your content:\n\n${autoFormattingEdits}\n\n(Note: Pay close attention to changes such as single quotes being converted to double quotes, semicolons being removed or added, long lines being broken into multiple lines, adjusting indentation style, adding/removing trailing commas, etc. This will help you ensure future SEARCH/REPLACE operations to this file are accurate.)\n\n` + : "") + + `Here is the full, updated content of the file that was saved:\n\n` + `\n${finalContent}\n\n\n` + - `Please note: If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including any auto-formatting done by the system).\n\n` + + `IMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference. This content reflects the current state of the file, including any auto-formatting (e.g., if you used single quotes but the formatter converted them to double quotes). Always base your SEARCH/REPLACE operations on this final version to ensure accuracy.\n\n` + `${newProblemsMessage}`, ) } await this.diffViewProvider.reset() + await this.saveCheckpoint() break } } catch (error) { await handleError("writing file", error) await this.diffViewProvider.revertChanges() await this.diffViewProvider.reset() + await this.saveCheckpoint() break } } @@ -1340,6 +1856,7 @@ export class Cline { if (!relPath) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("read_file", "path")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1359,16 +1876,19 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "tool") const didApprove = await askApproval("tool", completeMessage) if (!didApprove) { + await this.saveCheckpoint() break } } // now execute the tool like normal const content = await extractTextFromFile(absolutePath) pushToolResult(content) + await this.saveCheckpoint() break } } catch (error) { await handleError("reading file", error) + await this.saveCheckpoint() break } } @@ -1398,6 +1918,7 @@ export class Cline { if (!relDirPath) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("list_files", "path")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1419,14 +1940,17 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "tool") const didApprove = await askApproval("tool", completeMessage) if (!didApprove) { + await this.saveCheckpoint() break } } pushToolResult(result) + await this.saveCheckpoint() break } } catch (error) { await handleError("listing files", error) + await this.saveCheckpoint() break } } @@ -1453,9 +1977,8 @@ export class Cline { } else { if (!relDirPath) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("list_code_definition_names", "path"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("list_code_definition_names", "path")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1476,14 +1999,17 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "tool") const didApprove = await askApproval("tool", completeMessage) if (!didApprove) { + await this.saveCheckpoint() break } } pushToolResult(result) + await this.saveCheckpoint() break } } catch (error) { await handleError("parsing source code definitions", error) + await this.saveCheckpoint() break } } @@ -1515,11 +2041,13 @@ export class Cline { if (!relDirPath) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("search_files", "path")) + await this.saveCheckpoint() break } if (!regex) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("search_files", "regex")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1540,14 +2068,17 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "tool") const didApprove = await askApproval("tool", completeMessage) if (!didApprove) { + await this.saveCheckpoint() break } } pushToolResult(results) + await this.saveCheckpoint() break } } catch (error) { await handleError("searching files", error) + await this.saveCheckpoint() break } } @@ -1604,10 +2135,9 @@ export class Cline { if (action === "launch") { if (!url) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "url"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("browser_action", "url")) await this.browserSession.closeBrowser() + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1623,6 +2153,7 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "browser_action_launch") const didApprove = await askApproval("browser_action_launch", url) if (!didApprove) { + await this.saveCheckpoint() break } } @@ -1638,22 +2169,19 @@ export class Cline { if (!coordinate) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError( - "browser_action", - "coordinate", - ), + await this.sayAndCreateMissingParamError("browser_action", "coordinate"), ) await this.browserSession.closeBrowser() + await this.saveCheckpoint() break // can't be within an inner switch } } if (action === "type") { if (!text) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "text"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("browser_action", "text")) await this.browserSession.closeBrowser() + await this.saveCheckpoint() break } } @@ -1702,6 +2230,7 @@ export class Cline { browserActionResult.screenshot ? [browserActionResult.screenshot] : [], ), ) + await this.saveCheckpoint() break case "close": pushToolResult( @@ -1709,13 +2238,17 @@ export class Cline { `The browser has been closed. You may now proceed to using other tools.`, ), ) + await this.saveCheckpoint() break } + + await this.saveCheckpoint() break } } catch (error) { await this.browserSession.closeBrowser() // if any error occurs, the browser session is terminated await handleError("executing browser action", error) + await this.saveCheckpoint() break } } @@ -1736,29 +2269,22 @@ export class Cline { // ).catch(() => {}) } else { // don't need to remove last partial since we couldn't have streamed a say - await this.ask( - "command", - removeClosingTag("command", command), - block.partial, - ).catch(() => {}) + await this.ask("command", removeClosingTag("command", command), block.partial).catch(() => {}) } break } else { if (!command) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("execute_command", "command"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("execute_command", "command")) + await this.saveCheckpoint() break } if (!requiresApprovalRaw) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError( - "execute_command", - "requires_approval", - ), + await this.sayAndCreateMissingParamError("execute_command", "requires_approval"), ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1781,6 +2307,7 @@ export class Cline { `${this.shouldAutoApproveTool(block.name) && requiresApproval ? COMMAND_REQ_APP_STRING : ""}`, // ugly hack until we refactor combineCommandSequences ) if (!didApprove) { + await this.saveCheckpoint() break } } @@ -1805,10 +2332,12 @@ export class Cline { this.didRejectTool = true } pushToolResult(result) + await this.saveCheckpoint() break } } catch (error) { await handleError("executing command", error) + await this.saveCheckpoint() break } } @@ -1837,16 +2366,14 @@ export class Cline { } else { if (!server_name) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("use_mcp_tool", "server_name"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("use_mcp_tool", "server_name")) + await this.saveCheckpoint() break } if (!tool_name) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("use_mcp_tool", "tool_name"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("use_mcp_tool", "tool_name")) + await this.saveCheckpoint() break } // arguments are optional, but if they are provided they must be valid JSON @@ -1870,6 +2397,7 @@ export class Cline { formatResponse.invalidMcpToolArgumentError(server_name, tool_name), ), ) + await this.saveCheckpoint() break } } @@ -1881,7 +2409,12 @@ export class Cline { arguments: mcp_arguments, } satisfies ClineAskUseMcpServer) - if (this.shouldAutoApproveTool(block.name)) { + const isToolAutoApproved = this.providerRef + .deref() + ?.mcpHub?.connections?.find((conn) => conn.server.name === server_name) + ?.server.tools?.find((tool) => tool.name === tool_name)?.autoApprove + + if (this.shouldAutoApproveTool(block.name) && isToolAutoApproved) { this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") await this.say("use_mcp_server", completeMessage, undefined, false) this.consecutiveAutoApprovedRequestsCount++ @@ -1892,6 +2425,7 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "use_mcp_server") const didApprove = await askApproval("use_mcp_server", completeMessage) if (!didApprove) { + await this.saveCheckpoint() break } } @@ -1920,10 +2454,12 @@ export class Cline { .join("\n\n") || "(No response)" await this.say("mcp_server_response", toolResultPretty) pushToolResult(formatResponse.toolResult(toolResultPretty)) + await this.saveCheckpoint() break } } catch (error) { await handleError("executing MCP tool", error) + await this.saveCheckpoint() break } } @@ -1950,16 +2486,14 @@ export class Cline { } else { if (!server_name) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("access_mcp_resource", "server_name"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("access_mcp_resource", "server_name")) + await this.saveCheckpoint() break } if (!uri) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("access_mcp_resource", "uri"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("access_mcp_resource", "uri")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1980,15 +2514,14 @@ export class Cline { this.removeLastPartialMessageIfExistsWithType("say", "use_mcp_server") const didApprove = await askApproval("use_mcp_server", completeMessage) if (!didApprove) { + await this.saveCheckpoint() break } } // now execute the tool await this.say("mcp_server_request_started") - const resourceResult = await this.providerRef - .deref() - ?.mcpHub?.readResource(server_name, uri) + const resourceResult = await this.providerRef.deref()?.mcpHub?.readResource(server_name, uri) const resourceResultPretty = resourceResult?.contents .map((item) => { @@ -2001,10 +2534,12 @@ export class Cline { .join("\n\n") || "(Empty response)" await this.say("mcp_server_response", resourceResultPretty) pushToolResult(formatResponse.toolResult(resourceResultPretty)) + await this.saveCheckpoint() break } } catch (error) { await handleError("accessing MCP resource", error) + await this.saveCheckpoint() break } } @@ -2012,24 +2547,18 @@ export class Cline { const question: string | undefined = block.params.question try { if (block.partial) { - await this.ask("followup", removeClosingTag("question", question), block.partial).catch( - () => {}, - ) + await this.ask("followup", removeClosingTag("question", question), block.partial).catch(() => {}) break } else { if (!question) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("ask_followup_question", "question"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("ask_followup_question", "question")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 - if ( - this.autoApprovalSettings.enabled && - this.autoApprovalSettings.enableNotifications - ) { + if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) { showSystemNotification({ subtitle: "Cline has a question...", message: question.replace(/\n/g, " "), @@ -2039,10 +2568,62 @@ export class Cline { const { text, images } = await this.ask("followup", question, false) await this.say("user_feedback", text ?? "", images) pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) + await this.saveCheckpoint() break } } catch (error) { await handleError("asking question", error) + await this.saveCheckpoint() + break + } + } + case "plan_mode_response": { + const response: string | undefined = block.params.response + try { + if (block.partial) { + await this.ask("plan_mode_response", removeClosingTag("response", response), block.partial).catch( + () => {}, + ) + break + } else { + if (!response) { + this.consecutiveMistakeCount++ + pushToolResult(await this.sayAndCreateMissingParamError("plan_mode_response", "response")) + // await this.saveCheckpoint() + break + } + this.consecutiveMistakeCount = 0 + + // if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) { + // showSystemNotification({ + // subtitle: "Cline has a response...", + // message: response.replace(/\n/g, " "), + // }) + // } + + this.isAwaitingPlanResponse = true + const { text, images } = await this.ask("plan_mode_response", response, false) + this.isAwaitingPlanResponse = false + + if (this.didRespondToPlanAskBySwitchingMode) { + // await this.say("user_feedback", text ?? "", images) + pushToolResult( + formatResponse.toolResult( + `[The user has switched to ACT MODE, so you may now proceed with the task.]`, + images, + ), + ) + } else { + await this.say("user_feedback", text ?? "", images) + pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) + } + + // await this.saveCheckpoint() + break + } + } catch (error) { + await handleError("responding to inquiry", error) + // await this.saveCheckpoint() break } } @@ -2069,6 +2650,22 @@ export class Cline { */ const result: string | undefined = block.params.result const command: string | undefined = block.params.command + + const addNewChangesFlagToLastCompletionResultMessage = async () => { + // Add newchanges flag if there are new changes to the workspace + + const hasNewChanges = await this.doesLatestTaskCompletionHaveNewChanges() + const lastCompletionResultMessage = findLast(this.clineMessages, (m) => m.say === "completion_result") + if ( + lastCompletionResultMessage && + hasNewChanges && + !lastCompletionResultMessage.text?.endsWith(COMPLETION_RESULT_CHANGES_FLAG) + ) { + lastCompletionResultMessage.text += COMPLETION_RESULT_CHANGES_FLAG + } + await this.saveClineMessages() + } + try { const lastMessage = this.clineMessages.at(-1) if (block.partial) { @@ -2080,25 +2677,18 @@ export class Cline { // NOTE: we do not want to auto approve a command run as part of the attempt_completion tool if (lastMessage && lastMessage.ask === "command") { // update command - await this.ask( - "command", - removeClosingTag("command", command), - block.partial, - ).catch(() => {}) + await this.ask("command", removeClosingTag("command", command), block.partial).catch( + () => {}, + ) } else { // last message is completion_result // we have command string, which means we have the result as well, so finish it (doesnt have to exist yet) - await this.say( - "completion_result", - removeClosingTag("result", result), - undefined, - false, + await this.say("completion_result", removeClosingTag("result", result), undefined, false) + await this.saveCheckpoint() + await addNewChangesFlagToLastCompletionResultMessage() + await this.ask("command", removeClosingTag("command", command), block.partial).catch( + () => {}, ) - await this.ask( - "command", - removeClosingTag("command", command), - block.partial, - ).catch(() => {}) } } else { // no command, still outputting partial result @@ -2113,17 +2703,13 @@ export class Cline { } else { if (!result) { this.consecutiveMistakeCount++ - pushToolResult( - await this.sayAndCreateMissingParamError("attempt_completion", "result"), - ) + pushToolResult(await this.sayAndCreateMissingParamError("attempt_completion", "result")) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 - if ( - this.autoApprovalSettings.enabled && - this.autoApprovalSettings.enableNotifications - ) { + if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) { showSystemNotification({ subtitle: "Task Completed", message: result.replace(/\n/g, " "), @@ -2135,23 +2721,32 @@ export class Cline { if (lastMessage && lastMessage.ask !== "command") { // havent sent a command message yet so first send completion_result then command await this.say("completion_result", result, undefined, false) + await this.saveCheckpoint() + await addNewChangesFlagToLastCompletionResultMessage() + } else { + // we already sent a command message, meaning the complete completion message has also been sent + await this.saveCheckpoint() } // complete command message const didApprove = await askApproval("command", command) if (!didApprove) { + await this.saveCheckpoint() break } const [userRejected, execCommandResult] = await this.executeCommandTool(command!) if (userRejected) { this.didRejectTool = true pushToolResult(execCommandResult) + await this.saveCheckpoint() break } // user didn't reject, but the command may have output commandResult = execCommandResult } else { await this.say("completion_result", result, undefined, false) + await this.saveCheckpoint() + await addNewChangesFlagToLastCompletionResultMessage() } // we already sent completion_result says, an empty string asks relinquishes control over button and field @@ -2165,7 +2760,10 @@ export class Cline { const toolResults: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = [] if (commandResult) { if (typeof commandResult === "string") { - toolResults.push({ type: "text", text: commandResult }) + toolResults.push({ + type: "text", + text: commandResult, + }) } else if (Array.isArray(commandResult)) { toolResults.push(...commandResult) } @@ -2181,10 +2779,12 @@ export class Cline { }) this.userMessageContent.push(...toolResults) + // await this.saveCheckpoint() break } } catch (error) { await handleError("attempting completion", error) + await this.saveCheckpoint() break } } @@ -2201,7 +2801,7 @@ export class Cline { if (!block.partial || this.didRejectTool || this.didAlreadyUseTool) { // block is finished streaming and executing if (this.currentStreamingContentIndex === this.assistantMessageContent.length - 1) { - // its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssitantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented. + // its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssistantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented. // last block is complete and it is finished executing this.userMessageContentReady = true // will allow pwaitfor to continue } @@ -2226,6 +2826,7 @@ export class Cline { async recursivelyMakeClineRequests( userContent: UserContent, includeFileDetails: boolean = false, + isNewTask: boolean = false, ): Promise { if (this.abort) { throw new Error("Cline instance aborted") @@ -2284,17 +2885,33 @@ export class Cline { await this.say( "api_req_started", JSON.stringify({ - request: - userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", + request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", }), ) + // use this opportunity to initialize the checkpoint tracker (can be expensive to initialize in the constructor) + // FIXME: right now we're letting users init checkpoints for old tasks, but this could be a problem if opening a task in the wrong workspace + // isNewTask && + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create(this.taskId, this.providerRef.deref()) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + console.error("Failed to initialize checkpoint tracker:", errorMessage) + this.checkpointTrackerErrorMessage = errorMessage // will be displayed right away since we saveClineMessages next which posts state to webview + } + } + const [parsedUserContent, environmentDetails] = await this.loadContext(userContent, includeFileDetails) userContent = parsedUserContent // add environment details as its own text block, separate from tool results userContent.push({ type: "text", text: environmentDetails }) - await this.addToApiConversationHistory({ role: "user", content: userContent }) + await this.addToApiConversationHistory({ + role: "user", + content: userContent, + }) // since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started") @@ -2323,13 +2940,7 @@ export class Cline { cacheReads: cacheReadTokens, cost: totalCost ?? - calculateApiCost( - this.api.getModel().info, - inputTokens, - outputTokens, - cacheWriteTokens, - cacheReadTokens, - ), + calculateApiCost(this.api.getModel().info, inputTokens, outputTokens, cacheWriteTokens, cacheReadTokens), cancelReason, streamingFailedMessage, } satisfies ClineApiReqInfo) @@ -2372,7 +2983,7 @@ export class Cline { await this.saveClineMessages() // signals to provider that it can retrieve the saved messages from disk, as abortTask can not be awaited on in nature - this.didFinishAborting = true + this.didFinishAbortingStream = true } // reset streaming state @@ -2385,12 +2996,19 @@ export class Cline { this.didAlreadyUseTool = false this.presentAssistantMessageLocked = false this.presentAssistantMessageHasPendingUpdates = false + this.didAutomaticallyRetryFailedApiRequest = false await this.diffViewProvider.reset() const stream = this.attemptApiRequest(previousApiReqIndex) // yields only if the first chunk is successful, otherwise will allow the user to retry the request (most likely due to rate limit error, which gets thrown on the first chunk) let assistantMessage = "" + let reasoningMessage = "" + this.isStreaming = true try { for await (const chunk of stream) { + if (!chunk) { + // Sometimes chunk is undefined, no idea that can cause it, but this workaround seems to fix it + continue + } switch (chunk.type) { case "usage": inputTokens += chunk.inputTokens @@ -2399,7 +3017,16 @@ export class Cline { cacheReadTokens += chunk.cacheReadTokens ?? 0 totalCost = chunk.totalCost break + case "reasoning": + // reasoning will always come before assistant message + reasoningMessage += chunk.reasoning + await this.say("reasoning", reasoningMessage, undefined, true) + break case "text": + if (reasoningMessage && assistantMessage.length === 0) { + // complete reasoning message + await this.say("reasoning", reasoningMessage, undefined, false) + } assistantMessage += chunk.text // parse raw assistant message into content blocks const prevLength = this.assistantMessageContent.length @@ -2440,16 +3067,17 @@ export class Cline { // abandoned happens when extension is no longer waiting for the cline instance to finish aborting (error is thrown here when any function in the for loop throws due to this.abort) if (!this.abandoned) { this.abortTask() // if the stream failed, there's various states the task could be in (i.e. could have streamed some tools the user may have executed), so we just resort to replicating a cancel task - await abortStream( - "streaming_failed", - error.message ?? JSON.stringify(serializeError(error), null, 2), - ) + const errorMessage = this.formatErrorWithStatusCode(error) + + await abortStream("streaming_failed", errorMessage) const history = await this.providerRef.deref()?.getTaskWithId(this.taskId) if (history) { await this.providerRef.deref()?.initClineWithHistoryItem(history.historyItem) // await this.providerRef.deref()?.postStateToWebview() } } + } finally { + this.isStreaming = false } // need to call here in case the stream was aborted @@ -2495,7 +3123,9 @@ export class Cline { // if the model did not tool use, then we need to tell it to either use a tool or attempt_completion const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use") + if (!didToolUse) { + // normal request where tool use is required this.userMessageContent.push({ type: "text", text: formatResponse.noToolsUsed(), @@ -2513,7 +3143,12 @@ export class Cline { ) await this.addToApiConversationHistory({ role: "assistant", - content: [{ type: "text", text: "Failure: I did not provide a response." }], + content: [ + { + type: "text", + text: "Failure: I did not provide a response.", + }, + ], }) } @@ -2526,40 +3161,22 @@ export class Cline { async loadContext(userContent: UserContent, includeFileDetails: boolean = false) { return await Promise.all([ - // Process userContent array, which contains various block types: - // TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam. - // We need to apply parseMentions() to: - // 1. All TextBlockParam's text (first user message with task) - // 2. ToolResultBlockParam's content/context text arrays if it contains "" (see formatToolDeniedFeedback, attemptCompletion, executeCommand, and consecutiveMistakeCount >= 3) or "" (see askFollowupQuestion), we place all user generated content in these tags so they can effectively be used as markers for when we should parse mentions) + // This is a temporary solution to dynamically load context mentions from tool results. It checks for the presence of tags that indicate that the tool was rejected and feedback was provided (see formatToolDeniedFeedback, attemptCompletion, executeCommand, and consecutiveMistakeCount >= 3) or "" (see askFollowupQuestion), we place all user generated content in these tags so they can effectively be used as markers for when we should parse mentions). However if we allow multiple tools responses in the future, we will need to parse mentions specifically within the user content tags. + // (Note: this caused the @/ import alias bug where file contents were being parsed as well, since v2 converted tool results to text blocks) Promise.all( userContent.map(async (block) => { if (block.type === "text") { - return { - ...block, - text: await parseMentions(block.text, cwd, this.urlContentFetcher), - } - } else if (block.type === "tool_result") { - const isUserMessage = (text: string) => text.includes("") || text.includes("") - if (typeof block.content === "string" && isUserMessage(block.content)) { + // We need to ensure any user generated content is wrapped in one of these tags so that we know to parse mentions + // FIXME: Only parse text in between these tags instead of the entire text block which may contain other tool results. This is part of a larger issue where we shouldn't be using regex to parse mentions in the first place (ie for cases where file paths have spaces) + if ( + block.text.includes("") || + block.text.includes("") || + block.text.includes("") || + block.text.includes("") + ) { return { ...block, - content: await parseMentions(block.content, cwd, this.urlContentFetcher), - } - } else if (Array.isArray(block.content)) { - const parsedContent = await Promise.all( - block.content.map(async (contentBlock) => { - if (contentBlock.type === "text" && isUserMessage(contentBlock.text)) { - return { - ...contentBlock, - text: await parseMentions(contentBlock.text, cwd, this.urlContentFetcher), - } - } - return contentBlock - }), - ) - return { - ...block, - content: parsedContent, + text: await parseMentions(block.text, cwd, this.urlContentFetcher), } } } @@ -2684,6 +3301,22 @@ export class Cline { details += terminalDetails } + // Add current time information with timezone + const now = new Date() + const formatter = new Intl.DateTimeFormat(undefined, { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + hour12: true, + }) + const timeZone = formatter.resolvedOptions().timeZone + const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation + const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : ""}${timeZoneOffset}:00` + details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})` + if (includeFileDetails) { details += `\n\n# Current Working Directory (${cwd.toPosix()}) Files\n` const isDesktop = arePathsEqual(cwd, path.join(os.homedir(), "Desktop")) @@ -2697,6 +3330,17 @@ export class Cline { } } + details += "\n\n# Current Mode" + if (this.chatSettings.mode === "plan") { + details += "\nPLAN MODE" + details += + "\nIn this mode you should focus on information gathering, asking questions, and architecting a solution. Once you have a plan, use the plan_mode_response tool to engage in a conversational back and forth with the user. Do not use the plan_mode_response tool until you've gathered all the information you need e.g. with read_file or ask_followup_question." + details += + '\n(Remember: If it seems the user wants you to use tools only available in Act Mode, you should ask the user to "toggle to Act mode" (use those words) - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to Act Mode yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' + } else { + details += "\nACT MODE" + } + return `\n${details.trim()}\n` } } diff --git a/src/core/assistant-message/diff.ts b/src/core/assistant-message/diff.ts index d8f4056e41..4d577cd77a 100644 --- a/src/core/assistant-message/diff.ts +++ b/src/core/assistant-message/diff.ts @@ -6,11 +6,7 @@ * * Returns [matchIndexStart, matchIndexEnd] if found, or false if not found. */ -function lineTrimmedFallbackMatch( - originalContent: string, - searchContent: string, - startIndex: number, -): [number, number] | false { +function lineTrimmedFallbackMatch(originalContent: string, searchContent: string, startIndex: number): [number, number] | false { // Split both contents into lines const originalLines = originalContent.split("\n") const searchLines = searchContent.split("\n") @@ -91,11 +87,7 @@ function lineTrimmedFallbackMatch( * @param startIndex - The character index in originalContent where to start searching * @returns A tuple of [startIndex, endIndex] if a match is found, false otherwise */ -function blockAnchorFallbackMatch( - originalContent: string, - searchContent: string, - startIndex: number, -): [number, number] | false { +function blockAnchorFallbackMatch(originalContent: string, searchContent: string, startIndex: number): [number, number] | false { const originalLines = originalContent.split("\n") const searchLines = searchContent.split("\n") @@ -208,11 +200,7 @@ function blockAnchorFallbackMatch( * - If the search block cannot be matched using any of the available matching strategies, * an error is thrown. */ -export async function constructNewFileContent( - diffContent: string, - originalContent: string, - isFinal: boolean, -): Promise { +export async function constructNewFileContent(diffContent: string, originalContent: string, isFinal: boolean): Promise { let result = "" let lastProcessedIndex = 0 @@ -251,6 +239,13 @@ export async function constructNewFileContent( inSearch = false inReplace = true + // Remove trailing linebreak for adding the === marker + // if (currentSearchContent.endsWith("\r\n")) { + // currentSearchContent = currentSearchContent.slice(0, -2) + // } else if (currentSearchContent.endsWith("\n")) { + // currentSearchContent = currentSearchContent.slice(0, -1) + // } + if (!currentSearchContent) { // Empty search block if (originalContent.length === 0) { @@ -279,20 +274,12 @@ export async function constructNewFileContent( searchEndIndex = exactIndex + currentSearchContent.length } else { // Attempt fallback line-trimmed matching - const lineMatch = lineTrimmedFallbackMatch( - originalContent, - currentSearchContent, - lastProcessedIndex, - ) + const lineMatch = lineTrimmedFallbackMatch(originalContent, currentSearchContent, lastProcessedIndex) if (lineMatch) { ;[searchMatchIndex, searchEndIndex] = lineMatch } else { // Try block anchor fallback for larger blocks - const blockMatch = blockAnchorFallbackMatch( - originalContent, - currentSearchContent, - lastProcessedIndex, - ) + const blockMatch = blockAnchorFallbackMatch(originalContent, currentSearchContent, lastProcessedIndex) if (blockMatch) { ;[searchMatchIndex, searchEndIndex] = blockMatch } else { @@ -311,6 +298,14 @@ export async function constructNewFileContent( if (line === ">>>>>>> REPLACE") { // Finished one replace block + + // // Remove the artificially added linebreak in the last line of the REPLACE block + // if (result.endsWith("\r\n")) { + // result = result.slice(0, -2) + // } else if (result.endsWith("\n")) { + // result = result.slice(0, -1) + // } + // Advance lastProcessedIndex to after the matched section lastProcessedIndex = searchEndIndex @@ -325,6 +320,9 @@ export async function constructNewFileContent( } // Accumulate content for search or replace + // (currentReplaceContent is not being used for anything right now since we directly append to result.) + // (We artificially add a linebreak since we split on \n at the beginning. In order to not include a trailing linebreak in the final search/result blocks we need to remove it before using them. This allows for partial line matches to be correctly identified.) + // NOTE: search/replace blocks must be arranged in the order they appear in the file due to how we build the content using lastProcessedIndex. We also cannot strip the trailing newline since for non-partial lines it would remove the linebreak from the original content. (If we remove end linebreak from search, then we'd also have to remove it from replace but we can't know if it's a partial line or not since the model may be using the line break to indicate the end of the block rather than as part of the search content.) We require the model to output full lines in order for our fallbacks to work as well. if (inSearch) { currentSearchContent += line + "\n" } else if (inReplace) { diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index 7ad2c27d7b..e3ba253e0e 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -20,6 +20,7 @@ export const toolUseNames = [ "use_mcp_tool", "access_mcp_resource", "ask_followup_question", + "plan_mode_response", "attempt_completion", ] as const @@ -44,6 +45,7 @@ export const toolParamNames = [ "arguments", "uri", "question", + "response", "result", ] as const diff --git a/src/core/assistant-message/parse-assistant-message.ts b/src/core/assistant-message/parse-assistant-message.ts index e38e8f6458..2c37a650b6 100644 --- a/src/core/assistant-message/parse-assistant-message.ts +++ b/src/core/assistant-message/parse-assistant-message.ts @@ -1,12 +1,4 @@ -import { - AssistantMessageContent, - TextContent, - ToolUse, - ToolParamName, - toolParamNames, - toolUseNames, - ToolUseName, -} from "." +import { AssistantMessageContent, TextContent, ToolUse, ToolParamName, toolParamNames, toolUseNames, ToolUseName } from "." export function parseAssistantMessage(assistantMessage: string) { let contentBlocks: AssistantMessageContent[] = [] @@ -70,9 +62,7 @@ export function parseAssistantMessage(assistantMessage: string) { const contentStartIndex = toolContent.indexOf(contentStartTag) + contentStartTag.length const contentEndIndex = toolContent.lastIndexOf(contentEndTag) if (contentStartIndex !== -1 && contentEndIndex !== -1 && contentEndIndex > contentStartIndex) { - currentToolUse.params[contentParamName] = toolContent - .slice(contentStartIndex, contentEndIndex) - .trim() + currentToolUse.params[contentParamName] = toolContent.slice(contentStartIndex, contentEndIndex).trim() } } diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts index 05f33ba71a..e932f4042c 100644 --- a/src/core/prompts/responses.ts +++ b/src/core/prompts/responses.ts @@ -31,10 +31,7 @@ Otherwise, if you have not completed the task and do not need additional informa invalidMcpToolArgumentError: (serverName: string, toolName: string) => `Invalid JSON argument used with ${serverName} for ${toolName}. Please retry with a properly formatted JSON argument.`, - toolResult: ( - text: string, - images?: string[], - ): string | Array => { + toolResult: (text: string, images?: string[]): string | Array => { if (images && images.length > 0) { const textBlock: Anthropic.TextBlockParam = { type: "text", text } const imageBlocks: Anthropic.ImageBlockParam[] = formatImagesIntoBlocks(images) @@ -70,7 +67,10 @@ Otherwise, if you have not completed the task and do not need additional informa return 1 } // Otherwise, sort alphabetically - return aParts[i].localeCompare(bParts[i], undefined, { numeric: true, sensitivity: "base" }) + return aParts[i].localeCompare(bParts[i], undefined, { + numeric: true, + sensitivity: "base", + }) } } // If all parts are the same up to the length of the shorter path, @@ -106,7 +106,11 @@ const formatImagesIntoBlocks = (images?: string[]): Anthropic.ImageBlockParam[] const mimeType = rest.split(":")[1].split(";")[0] return { type: "image", - source: { type: "base64", media_type: mimeType, data: base64 }, + source: { + type: "base64", + media_type: mimeType, + data: base64, + }, } as Anthropic.ImageBlockParam }) : [] diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 1d3219a0d3..a043189438 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -1,12 +1,14 @@ -import defaultShell from "default-shell" +import { getShell } from "../../utils/shell" import os from "os" import osName from "os-name" import { McpHub } from "../../services/mcp/McpHub" +import { BrowserSettings } from "../../shared/BrowserSettings" export const SYSTEM_PROMPT = async ( cwd: string, supportsComputerUse: boolean, mcpHub: McpHub, + browserSettings: BrowserSettings, ) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. ==== @@ -36,7 +38,7 @@ Always adhere to this format for the tool use to ensure proper parsing and execu # Tools ## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: ${cwd.toPosix()} +Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: ${cwd.toPosix()} Parameters: - command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. - requires_approval: (required) A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations. @@ -87,6 +89,7 @@ Parameters: 2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence. * Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes. * Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change. + * When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. 3. Keep SEARCH/REPLACE blocks concise: * Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file. * Include just the changing lines, and a few surrounding lines if needed for uniqueness. @@ -142,7 +145,7 @@ Usage: Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action. - The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL. - While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result. -- The browser window has a resolution of **900x600** pixels. When performing any click actions, ensure the coordinates are within this resolution range. +- The browser window has a resolution of **${browserSettings.viewport.width}x${browserSettings.viewport.height}** pixels. When performing any click actions, ensure the coordinates are within this resolution range. - Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges. Parameters: - action: (required) The action to perform. The available actions are: @@ -160,7 +163,7 @@ Parameters: - Example: \`close\` - url: (optional) Use this for providing the URL for the \`launch\` action. * Example: https://example.com -- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **900x600** resolution. +- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **${browserSettings.viewport.width}x${browserSettings.viewport.height}** resolution. * Example: 450,300 - text: (optional) Use this for providing the text for the \`type\` action. * Example: Hello, world! @@ -174,6 +177,9 @@ Usage: : "" } +${ + mcpHub.getMode() !== "off" + ? ` ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. Parameters: @@ -202,6 +208,9 @@ Usage: server name here resource URI here +` + : "" +} ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. @@ -226,6 +235,15 @@ Your final result description here Command to demonstrate result (optional) +## plan_mode_response +Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should be used when you need to provide a response to a question or statement from the user about how you plan to accomplish the task. This tool is only available in PLAN MODE. The environment_details will specify the current mode, if it is not PLAN MODE then you should not use this tool. Depending on the user's message, you may ask questions to get clarification about the user's request, architect a solution to the task, and to brainstorm ideas with the user. For example, if the user's task is to create a website, you may start by asking some clarifying questions, then present a detailed plan for how you will accomplish the task given the context, and perhaps engage in a back and forth to finalize the details before the user switches you to ACT MODE to implement the solution. +Parameters: +- response: (required) The response to provide to the user. Do not try to use tools in this parameter, this is simply a chat response. +Usage: + +Your response here + + # Tool Use Examples ## Example 1: Requesting to execute a command @@ -235,27 +253,7 @@ Your final result description here false -## Example 2: Requesting to use an MCP tool - - -weather-server -get_forecast - -{ - "city": "San Francisco", - "days": 5 -} - - - -## Example 3: Requesting to access an MCP resource - - -weather-server -weather://san-francisco/current - - -## Example 4: Requesting to create a new file +## Example 2: Requesting to create a new file src/frontend-config.json @@ -277,7 +275,7 @@ Your final result description here -## Example 6: Requesting to make targeted edits to a file +## Example 3: Requesting to make targeted edits to a file src/components/App.tsx @@ -311,6 +309,31 @@ return ( >>>>>>> REPLACE +${ + mcpHub.getMode() !== "off" + ? ` + +## Example 4: Requesting to use an MCP tool + + +weather-server +get_forecast + +{ + "city": "San Francisco", + "days": 5 +} + + + +## Example 5: Requesting to access an MCP resource + + +weather-server +weather://san-francisco/current +` + : "" +} # Tool Use Guidelines @@ -333,6 +356,9 @@ It is crucial to proceed step-by-step, waiting for the user's message after each By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. +${ + mcpHub.getMode() !== "off" + ? ` ==== MCP SERVERS @@ -379,8 +405,13 @@ ${ }) .join("\n\n")}` : "(No MCP servers currently connected)" +}` + : "" } +${ + mcpHub.getMode() === "full" + ? ` ## Creating an MCP Server The user may ask you something along the lines of "add a tool" that does some function, in other words to create an MCP server that provides tools and resources that may connect to external APIs for example. You have the ability to create an MCP server and add it to a configuration file that will then expose the tools and resources for you to use with \`use_mcp_tool\` and \`access_mcp_resource\`. @@ -700,6 +731,8 @@ npm run build 5. Install the MCP Server by adding the MCP server configuration to the settings file located at '${await mcpHub.getMcpSettingsFilePath()}'. The settings file may have other MCP servers already configured, so you would read it first and then add your new server to the existing \`mcpServers\` object. +IMPORTANT: Regardless of what else you see in the MCP settings file, you must default any new MCP servers you create to disabled=false and autoApprove=[]. + \`\`\`json { "mcpServers": { @@ -723,12 +756,13 @@ npm run build ## Editing MCP Servers -The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: ${ - mcpHub - .getServers() - .map((server) => server.name) - .join(", ") || "(None running currently)" -}, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. +The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' below: ${ + mcpHub + .getServers() + .filter((server) => server.status === "connected") + .map((server) => server.name) + .join(", ") || "(None running currently)" + }, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. However some MCP servers may be running from installed packages rather than a local repository, in which case it may make more sense to create a new MCP server. @@ -737,6 +771,9 @@ However some MCP servers may be running from installed packages rather than a lo The user may not always request the use or creation of MCP servers. Instead, they might provide tasks that can be completed with existing tools. While using the MCP SDK to extend your capabilities can be useful, it's important to understand that this is just one specialized type of task you can accomplish. You should only implement MCP servers when the user explicitly requests it (e.g., "add a tool that..."). Remember: The MCP documentation and example provided above are to help you understand and work with existing MCP servers or create new ones when requested by the user. You already have access to tools and capabilities that can be used to accomplish a wide range of tasks. +` + : "" +} ==== @@ -788,7 +825,21 @@ You have access to two tools for working with files: **write_to_file** and **rep - The changes are so extensive that using replace_in_file would be more complex or risky - You need to completely reorganize or restructure a file - The file is relatively small and the changes affect most of its content - - You're generating boilerplate or template files + - You're generating boilerplate or template files + +# Auto-formatting Considerations + +- After using either write_to_file or replace_in_file, the user's editor may automatically format the file +- This auto-formatting may modify the file contents, for example: + - Breaking single lines into multiple lines + - Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs) + - Converting single quotes to double quotes (or vice versa based on project preferences) + - Organizing imports (e.g. sorting, grouping by type) + - Adding/removing trailing commas in objects and arrays + - Enforcing consistent brace style (e.g. same-line vs new-line) + - Standardizing semicolon usage (adding or removing based on style) +- The write_to_file and replace_in_file tool responses will include the final state of the file after any auto-formatting +- Use this final state as your reference point for any subsequent edits. This is ESPECIALLY important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly. # Workflow Tips @@ -801,6 +852,26 @@ By thoughtfully selecting between write_to_file and replace_in_file, you can mak ==== +ACT MODE V.S. PLAN MODE + +In each user message, the environment_details will specify the current mode. There are two modes: + +- ACT MODE: In this mode, you have access to all tools EXCEPT the plan_mode_response tool. + - In ACT MODE, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. +- PLAN MODE: In this special mode, you have access to the plan_mode_response tool. + - In PLAN MODE, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before they switch you to ACT MODE to implement the solution. + - In PLAN MODE, when you need to converse with the user or present a plan, you should use the plan_mode_response tool to deliver your response directly, rather than using tags to analyze when to respond. Do not talk about using plan_mode_response - just use it directly to share your thoughts and provide helpful answers. + +## What is PLAN MODE? + +- While you are usually in ACT MODE, the user may switch to PLAN MODE in order to have a back and forth with you to plan how to best accomplish the task. +- When starting in PLAN MODE, depending on the user's request, you may need to do some information gathering e.g. using read_file or search_files to get more context about the task. You may also ask the user clarifying questions to get a better understanding of the task. +- Once you've gained more context about the user's request, you should architect a detailed plan for how you will accomplish the task. +- Then you might ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +- Finally once it seems like you've reached a good plan, ask the user to switch you back to ACT MODE to implement the solution. + +==== + CAPABILITIES - You have access to tools that let you execute CLI commands on the user's computer, list files, view source code definitions, regex search${ @@ -815,7 +886,13 @@ CAPABILITIES ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." : "" } +${ + mcpHub.getMode() !== "off" + ? ` - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. +` + : "" +} ==== @@ -836,7 +913,7 @@ RULES - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${ supportsComputerUse - ? '\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.' + ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.getMode() !== "off" ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` : "" } - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. @@ -844,19 +921,27 @@ RULES - When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task. - At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. - Before executing commands, check the "Actively Running Terminals" section in environment_details. If present, consider how these active processes might impact your task. For example, if a local development server is already running, you wouldn't need to start it again. If no active terminals are listed, proceed with command execution as normal. -- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. +- When using the replace_in_file tool, you must include complete lines in your SEARCH blocks, not partial lines. The system requires exact line matches and cannot match partial lines. For example, if you want to match a line containing "const x = 5;", your SEARCH block must include the entire line, not just "x = 5" or other fragments. +- When using the replace_in_file tool, if you use multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. For example if you need to make changes to both line 10 and line 50, first include the SEARCH/REPLACE block for line 10, followed by the SEARCH/REPLACE block for line 50. - It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ supportsComputerUse ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." : "" } +${ + mcpHub.getMode() !== "off" + ? ` +- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. +` + : "" +} ==== SYSTEM INFORMATION Operating System: ${osName()} -Default Shell: ${defaultShell} +Default Shell: ${getShell()} Home Directory: ${os.homedir().toPosix()} Current Working Directory: ${cwd.toPosix()} diff --git a/src/core/sliding-window/index.ts b/src/core/sliding-window/index.ts index caa604bc57..69c804199e 100644 --- a/src/core/sliding-window/index.ts +++ b/src/core/sliding-window/index.ts @@ -8,19 +8,90 @@ a 200k context, we can assume that the first half is likely irrelevant to their Therefore, this function should only be called when absolutely necessary to fit within context limits, not as a continuous process. */ -export function truncateHalfConversation( +// export function truncateHalfConversation( +// messages: Anthropic.Messages.MessageParam[], +// ): Anthropic.Messages.MessageParam[] { +// // API expects messages to be in user-assistant order, and tool use messages must be followed by tool results. We need to maintain this structure while truncating. + +// // Always keep the first Task message (this includes the project's file structure in environment_details) +// const truncatedMessages = [messages[0]] + +// // Remove half of user-assistant pairs +// const messagesToRemove = Math.floor(messages.length / 4) * 2 // has to be even number + +// const remainingMessages = messages.slice(messagesToRemove + 1) // has to start with assistant message since tool result cannot follow assistant message with no tool use +// truncatedMessages.push(...remainingMessages) + +// return truncatedMessages +// } + +/* +getNextTruncationRange: Calculates the next range of messages to be "deleted" +- Takes the full messages array and optional current deleted range +- Always preserves the first message (task message) +- Removes 1/2 of remaining messages (rounded down to even number) after current deleted range +- Returns [startIndex, endIndex] representing inclusive range to delete + +getTruncatedMessages: Constructs the truncated array using the deleted range +- Takes full messages array and optional deleted range +- Returns new array with messages in deleted range removed +- Preserves order and structure of remaining messages + +The range is represented as [startIndex, endIndex] where both indices are inclusive +The functions maintain the original array integrity while allowing progressive truncation +through the deletedRange parameter + +Usage example: +const messages = [user1, assistant1, user2, assistant2, user3, assistant3]; +let deletedRange = getNextTruncationRange(messages); // [1,2] (assistant1,user2) +let truncated = getTruncatedMessages(messages, deletedRange); +// [user1, assistant2, user3, assistant3] + +deletedRange = getNextTruncationRange(messages, deletedRange); // [2,3] (assistant2,user3) +truncated = getTruncatedMessages(messages, deletedRange); +// [user1, assistant3] +*/ + +export function getNextTruncationRange( messages: Anthropic.Messages.MessageParam[], -): Anthropic.Messages.MessageParam[] { - // API expects messages to be in user-assistant order, and tool use messages must be followed by tool results. We need to maintain this structure while truncating. + currentDeletedRange: [number, number] | undefined = undefined, + keep: "half" | "quarter" = "half", +): [number, number] { + // Since we always keep the first message, currentDeletedRange[0] will always be 1 (for now until we have a smarter truncation algorithm) + const rangeStartIndex = 1 + const startOfRest = currentDeletedRange ? currentDeletedRange[1] + 1 : 1 - // Always keep the first Task message (this includes the project's file structure in environment_details) - const truncatedMessages = [messages[0]] + let messagesToRemove: number + if (keep === "half") { + // Remove half of user-assistant pairs + messagesToRemove = Math.floor((messages.length - startOfRest) / 4) * 2 // Keep even number + } else { + // Remove 3/4 of user-assistant pairs + messagesToRemove = Math.floor((messages.length - startOfRest) / 8) * 3 * 2 + } - // Remove half of user-assistant pairs - const messagesToRemove = Math.floor(messages.length / 4) * 2 // has to be even number + let rangeEndIndex = startOfRest + messagesToRemove - 1 - const remainingMessages = messages.slice(messagesToRemove + 1) // has to start with assistant message since tool result cannot follow assistant message with no tool use - truncatedMessages.push(...remainingMessages) + // Make sure the last message being removed is a user message, so that the next message after the initial task message is an assistant message. This preservers the user-assistant-user-assistant structure. + // NOTE: anthropic format messages are always user-assistant-user-assistant, while openai format messages can have multiple user messages in a row (we use anthropic format throughout cline) + if (messages[rangeEndIndex].role !== "user") { + rangeEndIndex -= 1 + } - return truncatedMessages + // this is an inclusive range that will be removed from the conversation history + return [rangeStartIndex, rangeEndIndex] +} + +export function getTruncatedMessages( + messages: Anthropic.Messages.MessageParam[], + deletedRange: [number, number] | undefined, +): Anthropic.Messages.MessageParam[] { + if (!deletedRange) { + return messages + } + + const [start, end] = deletedRange + // the range is inclusive - both start and end indices and everything in between will be removed from the final result. + // NOTE: if you try to console log these, don't forget that logging a reference to an array may not provide the same result as logging a slice() snapshot of that array at that exact moment. The following DOES in fact include the latest assistant message. + return [...messages.slice(0, start), ...messages.slice(end + 1)] } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 8a556f9369..a15b99ed05 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -2,6 +2,8 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" import fs from "fs/promises" import os from "os" +import crypto from "crypto" +import { execa } from "execa" import pWaitFor from "p-wait-for" import * as path from "path" import * as vscode from "vscode" @@ -12,17 +14,20 @@ import { selectImages } from "../../integrations/misc/process-images" import { getTheme } from "../../integrations/theme/getTheme" import WorkspaceTracker from "../../integrations/workspace/WorkspaceTracker" import { McpHub } from "../../services/mcp/McpHub" +import { FirebaseAuthManager, UserInfo } from "../../services/auth/FirebaseAuthManager" import { ApiProvider, ModelInfo } from "../../shared/api" import { findLast } from "../../shared/array" -import { ExtensionMessage } from "../../shared/ExtensionMessage" +import { ExtensionMessage, ExtensionState } from "../../shared/ExtensionMessage" import { HistoryItem } from "../../shared/HistoryItem" -import { WebviewMessage } from "../../shared/WebviewMessage" +import { ClineCheckpointRestore, WebviewMessage } from "../../shared/WebviewMessage" import { fileExistsAtPath } from "../../utils/fs" import { Cline } from "../Cline" import { openMention } from "../mentions" import { getNonce } from "./getNonce" import { getUri } from "./getUri" import { AutoApprovalSettings, DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../shared/AutoApprovalSettings" +import { BrowserSettings, DEFAULT_BROWSER_SETTINGS } from "../../shared/BrowserSettings" +import { ChatSettings, DEFAULT_CHAT_SETTINGS } from "../../shared/ChatSettings" /* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts @@ -39,6 +44,10 @@ type SecretKey = | "openAiApiKey" | "geminiApiKey" | "openAiNativeApiKey" + | "deepSeekApiKey" + | "mistralApiKey" + | "authToken" + | "authNonce" type GlobalStateKey = | "apiProvider" | "apiModelId" @@ -60,6 +69,15 @@ type GlobalStateKey = | "openRouterModelId" | "openRouterModelInfo" | "autoApprovalSettings" + | "browserSettings" + | "chatSettings" + | "vsCodeLmModelSelector" + | "userInfo" + | "previousModeApiProvider" + | "previousModeModelId" + | "previousModeModelInfo" + | "liteLlmBaseUrl" + | "liteLlmModelId" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -78,7 +96,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { private cline?: Cline private workspaceTracker?: WorkspaceTracker mcpHub?: McpHub - private latestAnnouncementId = "dec-17-2024" // update to some unique identifier when we add a new announcement + private authManager: FirebaseAuthManager + private latestAnnouncementId = "jan-20-2025" // update to some unique identifier when we add a new announcement constructor( readonly context: vscode.ExtensionContext, @@ -88,6 +107,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { ClineProvider.activeInstances.add(this) this.workspaceTracker = new WorkspaceTracker(this) this.mcpHub = new McpHub(this) + this.authManager = new FirebaseAuthManager(this) } /* @@ -113,10 +133,29 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.workspaceTracker = undefined this.mcpHub?.dispose() this.mcpHub = undefined + this.authManager.dispose() this.outputChannel.appendLine("Disposed all disposables") ClineProvider.activeInstances.delete(this) } + // Auth methods + async handleSignOut() { + try { + await this.authManager.signOut() + vscode.window.showInformationMessage("Successfully logged out of Cline") + } catch (error) { + vscode.window.showErrorMessage("Logout failed") + } + } + + async setAuthToken(token?: string) { + await this.storeSecret("authToken", token) + } + + async setUserInfo(info?: { displayName: string | null; email: string | null; photoURL: string | null }) { + await this.updateGlobalState("userInfo", info) + } + public static getVisibleInstance(): ClineProvider | undefined { return findLast(Array.from(this.activeInstances), (instance) => instance.view?.visible === true) } @@ -137,7 +176,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { webviewView.webview.html = this.getHtmlContent(webviewView.webview) // Sets up an event listener to listen for messages passed from the webview view context - // and executes code based on the message that is recieved + // and executes code based on the message that is received this.setWebviewMessageListener(webviewView.webview) // Logs show up in bottom panel > Debug Console @@ -151,7 +190,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { webviewView.onDidChangeViewState( () => { if (this.view?.visible) { - this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) + this.postMessageToWebview({ + type: "action", + action: "didBecomeVisible", + }) } }, null, @@ -162,7 +204,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { webviewView.onDidChangeVisibility( () => { if (this.view?.visible) { - this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) + this.postMessageToWebview({ + type: "action", + action: "didBecomeVisible", + }) } }, null, @@ -185,7 +230,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { async (e) => { if (e && e.affectsConfiguration("workbench.colorTheme")) { // Sends latest theme name to webview - await this.postMessageToWebview({ type: "theme", text: JSON.stringify(await getTheme()) }) + await this.postMessageToWebview({ + type: "theme", + text: JSON.stringify(await getTheme()), + }) } }, null, @@ -199,18 +247,31 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async initClineWithTask(task?: string, images?: string[]) { - await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one - const { apiConfiguration, customInstructions, autoApprovalSettings } = await this.getState() - this.cline = new Cline(this, apiConfiguration, autoApprovalSettings, customInstructions, task, images) - } - - async initClineWithHistoryItem(historyItem: HistoryItem) { - await this.clearTask() - const { apiConfiguration, customInstructions, autoApprovalSettings } = await this.getState() + await this.clearTask() // ensures that an existing task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = + await this.getState() this.cline = new Cline( this, apiConfiguration, autoApprovalSettings, + browserSettings, + chatSettings, + customInstructions, + task, + images, + ) + } + + async initClineWithHistoryItem(historyItem: HistoryItem) { + await this.clearTask() + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = + await this.getState() + this.cline = new Cline( + this, + apiConfiguration, + autoApprovalSettings, + browserSettings, + chatSettings, customInstructions, undefined, undefined, @@ -239,13 +300,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { // then convert it to a uri we can use in the webview. // The CSS file from the React build output - const stylesUri = getUri(webview, this.context.extensionUri, [ - "webview-ui", - "build", - "static", - "css", - "main.css", - ]) + const stylesUri = getUri(webview, this.context.extensionUri, ["webview-ui", "build", "static", "css", "main.css"]) // The JS file from the React build output const scriptUri = getUri(webview, this.context.extensionUri, ["webview-ui", "build", "static", "js", "main.js"]) @@ -290,7 +345,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { - + Cline @@ -306,7 +361,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { /** * Sets up an event listener to listen for messages passed from the webview context and - * executes code based on the message that is recieved. + * executes code based on the message that is received. * * @param webview A reference to the extension webview */ @@ -318,12 +373,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.postStateToWebview() this.workspaceTracker?.initializeFilePaths() // don't await getTheme().then((theme) => - this.postMessageToWebview({ type: "theme", text: JSON.stringify(theme) }), + this.postMessageToWebview({ + type: "theme", + text: JSON.stringify(theme), + }), ) // post last cached models in case the call to endpoint fails this.readOpenRouterModels().then((openRouterModels) => { if (openRouterModels) { - this.postMessageToWebview({ type: "openRouterModels", openRouterModels }) + this.postMessageToWebview({ + type: "openRouterModels", + openRouterModels, + }) } }) // gui relies on model info to be up-to-date to provide the most accurate pricing, so we need to fetch the latest details on launch. @@ -378,9 +439,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, + deepSeekApiKey, + mistralApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, + vsCodeLmModelSelector, + liteLlmBaseUrl, + liteLlmModelId, } = message.apiConfiguration await this.updateGlobalState("apiProvider", apiProvider) await this.updateGlobalState("apiModelId", apiModelId) @@ -403,9 +469,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("anthropicBaseUrl", anthropicBaseUrl) await this.storeSecret("geminiApiKey", geminiApiKey) await this.storeSecret("openAiNativeApiKey", openAiNativeApiKey) + await this.storeSecret("deepSeekApiKey", deepSeekApiKey) + await this.storeSecret("mistralApiKey", mistralApiKey) await this.updateGlobalState("azureApiVersion", azureApiVersion) await this.updateGlobalState("openRouterModelId", openRouterModelId) await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) + await this.updateGlobalState("vsCodeLmModelSelector", vsCodeLmModelSelector) + await this.updateGlobalState("liteLlmBaseUrl", liteLlmBaseUrl) + await this.updateGlobalState("liteLlmModelId", liteLlmModelId) if (this.cline) { this.cline.api = buildApiHandler(message.apiConfiguration) } @@ -424,6 +495,118 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postStateToWebview() } break + case "browserSettings": + if (message.browserSettings) { + await this.updateGlobalState("browserSettings", message.browserSettings) + if (this.cline) { + this.cline.updateBrowserSettings(message.browserSettings) + } + await this.postStateToWebview() + } + break + case "chatSettings": + if (message.chatSettings) { + const didSwitchToActMode = message.chatSettings.mode === "act" + + // Get previous model info that we will revert to after saving current mode api info + const { + apiConfiguration, + previousModeApiProvider: newApiProvider, + previousModeModelId: newModelId, + previousModeModelInfo: newModelInfo, + } = await this.getState() + + // Save the last model used in this mode + await this.updateGlobalState("previousModeApiProvider", apiConfiguration.apiProvider) + switch (apiConfiguration.apiProvider) { + case "anthropic": + case "bedrock": + case "vertex": + case "gemini": + await this.updateGlobalState("previousModeModelId", apiConfiguration.apiModelId) + break + case "openrouter": + await this.updateGlobalState("previousModeModelId", apiConfiguration.openRouterModelId) + await this.updateGlobalState("previousModeModelInfo", apiConfiguration.openRouterModelInfo) + break + case "vscode-lm": + await this.updateGlobalState("previousModeModelId", apiConfiguration.vsCodeLmModelSelector) + break + case "openai": + await this.updateGlobalState("previousModeModelId", apiConfiguration.openAiModelId) + break + case "ollama": + await this.updateGlobalState("previousModeModelId", apiConfiguration.ollamaModelId) + break + case "lmstudio": + await this.updateGlobalState("previousModeModelId", apiConfiguration.lmStudioModelId) + break + case "litellm": + await this.updateGlobalState("previousModeModelId", apiConfiguration.liteLlmModelId) + break + } + + // Restore the model used in previous mode + if (newApiProvider && newModelId) { + await this.updateGlobalState("apiProvider", newApiProvider) + switch (newApiProvider) { + case "anthropic": + case "bedrock": + case "vertex": + case "gemini": + await this.updateGlobalState("apiModelId", newModelId) + break + case "openrouter": + await this.updateGlobalState("openRouterModelId", newModelId) + await this.updateGlobalState("openRouterModelInfo", newModelInfo) + break + case "vscode-lm": + await this.updateGlobalState("vsCodeLmModelSelector", newModelId) + break + case "openai": + await this.updateGlobalState("openAiModelId", newModelId) + break + case "ollama": + await this.updateGlobalState("ollamaModelId", newModelId) + break + case "lmstudio": + await this.updateGlobalState("lmStudioModelId", newModelId) + break + case "litellm": + await this.updateGlobalState("liteLlmModelId", newModelId) + break + } + + if (this.cline) { + const { apiConfiguration: updatedApiConfiguration } = await this.getState() + this.cline.api = buildApiHandler(updatedApiConfiguration) + } + } + + await this.updateGlobalState("chatSettings", message.chatSettings) + await this.postStateToWebview() + // console.log("chatSettings", message.chatSettings) + if (this.cline) { + this.cline.updateChatSettings(message.chatSettings) + if (this.cline.isAwaitingPlanResponse && didSwitchToActMode) { + this.cline.didRespondToPlanAskBySwitchingMode = true + // this is necessary for the webview to update accordingly, but Cline instance will not send text back as feedback message + await this.postMessageToWebview({ + type: "invoke", + invoke: "sendMessage", + text: "[Proceeding with the task...]", + }) + } else { + this.cancelTask() + } + } + } + break + // case "relaunchChromeDebugMode": + // if (this.cline) { + // this.cline.browserSession.relaunchChromeDebugMode() + // } + // break case "askResponse": this.cline?.handleWebviewAskResponse(message.askResponse!, message.text, message.images) break @@ -438,7 +621,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { break case "selectImages": const images = await selectImages() - await this.postMessageToWebview({ type: "selectedImages", images }) + await this.postMessageToWebview({ + type: "selectedImages", + images, + }) break case "exportCurrentTask": const currentTaskId = this.cline?.taskId @@ -460,15 +646,33 @@ export class ClineProvider implements vscode.WebviewViewProvider { break case "requestOllamaModels": const ollamaModels = await this.getOllamaModels(message.text) - this.postMessageToWebview({ type: "ollamaModels", ollamaModels }) + this.postMessageToWebview({ + type: "ollamaModels", + ollamaModels, + }) break case "requestLmStudioModels": const lmStudioModels = await this.getLmStudioModels(message.text) - this.postMessageToWebview({ type: "lmStudioModels", lmStudioModels }) + this.postMessageToWebview({ + type: "lmStudioModels", + lmStudioModels, + }) + break + case "requestVsCodeLmModels": + const vsCodeLmModels = await this.getVsCodeLmModels() + this.postMessageToWebview({ type: "vsCodeLmModels", vsCodeLmModels }) break case "refreshOpenRouterModels": await this.refreshOpenRouterModels() break + case "refreshOpenAiModels": + const { apiConfiguration } = await this.getState() + const openAiModels = await this.getOpenAiModels( + apiConfiguration.openAiBaseUrl, + apiConfiguration.openAiApiKey, + ) + this.postMessageToWebview({ type: "openAiModels", openAiModels }) + break case "openImage": openImage(message.text!) break @@ -478,24 +682,63 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "openMention": openMention(message.text) break - case "cancelTask": - if (this.cline) { - const { historyItem } = await this.getTaskWithId(this.cline.taskId) - this.cline.abortTask() - await pWaitFor(() => this.cline === undefined || this.cline.didFinishAborting, { + case "checkpointDiff": { + if (message.number) { + await this.cline?.presentMultifileDiff(message.number, false) + } + break + } + case "checkpointRestore": { + await this.cancelTask() // we cannot alter message history say if the task is active, as it could be in the middle of editing a file or running a command, which expect the ask to be responded to rather than being superceded by a new message eg add deleted_api_reqs + // cancel task waits for any open editor to be reverted and starts a new cline instance + if (message.number) { + // wait for messages to be loaded + await pWaitFor(() => this.cline?.isInitialized === true, { timeout: 3_000, }).catch(() => { - console.error("Failed to abort task") + console.error("Failed to init new cline instance") }) - if (this.cline) { - // 'abandoned' will prevent this cline instance from affecting future cline instance gui. this may happen if its hanging on a streaming request - this.cline.abandoned = true - } - await this.initClineWithHistoryItem(historyItem) // clears task again, so we need to abortTask manually above - // await this.postStateToWebview() // new Cline instance will post state when it's ready. having this here sent an empty messages array to webview leading to virtuoso having to reload the entire list + // NOTE: cancelTask awaits abortTask, which awaits diffViewProvider.revertChanges, which reverts any edited files, allowing us to reset to a checkpoint rather than running into a state where the revertChanges function is called alongside or after the checkpoint reset + await this.cline?.restoreCheckpoint(message.number, message.text! as ClineCheckpointRestore) } - break + } + case "taskCompletionViewChanges": { + if (message.number) { + await this.cline?.presentMultifileDiff(message.number, true) + } + break + } + case "cancelTask": + this.cancelTask() + break + case "getLatestState": + await this.postStateToWebview() + break + case "subscribeEmail": + this.subscribeEmail(message.text) + break + case "accountLoginClicked": { + // Generate nonce for state validation + const nonce = crypto.randomBytes(32).toString("hex") + await this.storeSecret("authNonce", nonce) + + // Open browser for authentication with state param + console.log("Login button clicked in account page") + console.log("Opening auth page with state param") + + const uriScheme = vscode.env.uriScheme + + const authUrl = vscode.Uri.parse( + `https://app.cline.bot/auth?state=${encodeURIComponent(nonce)}&callback_url=${encodeURIComponent(`${uriScheme || "vscode"}://saoudrizwan.claude-dev/auth`)}`, + ) + vscode.env.openExternal(authUrl) + break + } + case "accountLogoutClicked": { + await this.handleSignOut() + break + } case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { @@ -503,6 +746,22 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "toggleMcpServer": { + try { + await this.mcpHub?.toggleServerDisabled(message.serverName!, message.disabled!) + } catch (error) { + console.error(`Failed to toggle MCP server ${message.serverName}:`, error) + } + break + } + case "toggleToolAutoApprove": { + try { + await this.mcpHub?.toggleToolAutoApprove(message.serverName!, message.toolName!, message.autoApprove!) + } catch (error) { + console.error(`Failed to toggle auto-approve for tool ${message.toolName}:`, error) + } + break + } case "restartMcpServer": { try { await this.mcpHub?.restartConnection(message.text!) @@ -511,6 +770,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "openExtensionSettings": { + const settingsFilter = message.text || "" + await vscode.commands.executeCommand( + "workbench.action.openSettings", + `@ext:saoudrizwan.claude-dev ${settingsFilter}`.trim(), // trim whitespace if no settings filter + ) + break + } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) } @@ -520,6 +787,65 @@ export class ClineProvider implements vscode.WebviewViewProvider { ) } + async subscribeEmail(email?: string) { + if (!email) { + return + } + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + if (!emailRegex.test(email)) { + vscode.window.showErrorMessage("Please enter a valid email address") + return + } + console.log("Subscribing email:", email) + this.postMessageToWebview({ type: "emailSubscribed" }) + // Currently ignoring errors to this endpoint, but after accounts we'll remove this anyways + try { + const response = await axios.post( + "https://app.cline.bot/api/mailing-list", + { + email: email, + }, + { + headers: { + "Content-Type": "application/json", + }, + }, + ) + console.log("Email subscribed successfully. Response:", response.data) + } catch (error) { + console.error("Failed to subscribe email:", error) + } + } + + async cancelTask() { + if (this.cline) { + const { historyItem } = await this.getTaskWithId(this.cline.taskId) + try { + await this.cline.abortTask() + } catch (error) { + console.error("Failed to abort task", error) + } + await pWaitFor( + () => + this.cline === undefined || + this.cline.isStreaming === false || + this.cline.didFinishAbortingStream || + this.cline.isWaitingForFirstChunk, // if only first chunk is processed, then there's no need to wait for graceful abort (closes edits, browser, etc) + { + timeout: 3_000, + }, + ).catch(() => { + console.error("Failed to abort task") + }) + if (this.cline) { + // 'abandoned' will prevent this cline instance from affecting future cline instance gui. this may happen if its hanging on a streaming request + this.cline.abandoned = true + } + await this.initClineWithHistoryItem(historyItem) // clears task again, so we need to abortTask manually above + // await this.postStateToWebview() // new Cline instance will post state when it's ready. having this here sent an empty messages array to webview leading to virtuoso having to reload the entire list + } + } + async updateCustomInstructions(instructions?: string) { // User may be clearing the field await this.updateGlobalState("customInstructions", instructions || undefined) @@ -531,8 +857,28 @@ export class ClineProvider implements vscode.WebviewViewProvider { // MCP + async getDocumentsPath(): Promise { + if (process.platform === "win32") { + // If the user is running Win 7/Win Server 2008 r2+, we want to get the correct path to their Documents directory. + try { + const { stdout: docsPath } = await execa("powershell", [ + "-NoProfile", // Ignore user's PowerShell profile(s) + "-Command", + "[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::MyDocuments)", + ]) + return docsPath.trim() + } catch (err) { + console.error("Failed to retrieve Windows Documents path. Falling back to homedir/Documents.") + return path.join(os.homedir(), "Documents") + } + } else { + return path.join(os.homedir(), "Documents") // On POSIX (macOS, Linux, etc.), assume ~/Documents by default (existing behavior, but may want to implement similar logic here) + } + } + async ensureMcpServersDirectoryExists(): Promise { - const mcpServersDir = path.join(os.homedir(), "Documents", "Cline", "MCP") + const userDocumentsPath = await this.getDocumentsPath() + const mcpServersDir = path.join(userDocumentsPath, "Cline", "MCP") try { await fs.mkdir(mcpServersDir, { recursive: true }) } catch (error) { @@ -547,6 +893,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { return settingsDir } + // VSCode LM API + + private async getVsCodeLmModels() { + try { + const models = await vscode.lm.selectChatModels({}) + return models || [] + } catch (error) { + console.error("Error fetching VS Code LM models:", error) + return [] + } + } + // Ollama async getOllamaModels(baseUrl?: string) { @@ -585,6 +943,58 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } + // Auth + + public async validateAuthState(state: string | null): Promise { + const storedNonce = await this.getSecret("authNonce") + if (!state || state !== storedNonce) { + return false + } + await this.storeSecret("authNonce", undefined) // Clear after use + return true + } + + async handleAuthCallback(token: string) { + try { + // First sign in with Firebase to trigger auth state change + await this.authManager.signInWithCustomToken(token) + + // Then store the token securely + await this.storeSecret("authToken", token) + await this.postStateToWebview() + vscode.window.showInformationMessage("Successfully logged in to Cline") + } catch (error) { + console.error("Failed to handle auth callback:", error) + vscode.window.showErrorMessage("Failed to log in to Cline") + } + } + + // OpenAi + + async getOpenAiModels(baseUrl?: string, apiKey?: string) { + try { + if (!baseUrl) { + return [] + } + + if (!URL.canParse(baseUrl)) { + return [] + } + + const config: Record = {} + if (apiKey) { + config["headers"] = { Authorization: `Bearer ${apiKey}` } + } + + const response = await axios.get(`${baseUrl}/models`, config) + const modelsArray = response.data?.data?.map((model: any) => model.id) || [] + const models = [...new Set(modelsArray)] + return models + } catch (error) { + return [] + } + } + // OpenRouter async handleOpenRouterCallback(code: string) { @@ -606,7 +1016,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.storeSecret("openRouterApiKey", apiKey) await this.postStateToWebview() if (this.cline) { - this.cline.api = buildApiHandler({ apiProvider: openrouter, openRouterApiKey: apiKey }) + this.cline.api = buildApiHandler({ + apiProvider: openrouter, + openRouterApiKey: apiKey, + }) } // await this.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) // bad ux if user is on welcome } @@ -618,10 +1031,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async readOpenRouterModels(): Promise | undefined> { - const openRouterModelsFilePath = path.join( - await this.ensureCacheDirectoryExists(), - GlobalFileNames.openRouterModels, - ) + const openRouterModelsFilePath = path.join(await this.ensureCacheDirectoryExists(), GlobalFileNames.openRouterModels) const fileExists = await fileExistsAtPath(openRouterModelsFilePath) if (fileExists) { const fileContents = await fs.readFile(openRouterModelsFilePath, "utf8") @@ -631,10 +1041,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async refreshOpenRouterModels() { - const openRouterModelsFilePath = path.join( - await this.ensureCacheDirectoryExists(), - GlobalFileNames.openRouterModels, - ) + const openRouterModelsFilePath = path.join(await this.ensureCacheDirectoryExists(), GlobalFileNames.openRouterModels) let models: Record = {} try { @@ -723,6 +1130,13 @@ export class ClineProvider implements vscode.WebviewViewProvider { modelInfo.cacheWritesPrice = 0.3 modelInfo.cacheReadsPrice = 0.03 break + case "deepseek/deepseek-chat": + modelInfo.supportsPromptCache = true + // see api.ts/deepSeekModels for more info + modelInfo.inputPrice = 0 + modelInfo.cacheWritesPrice = 0.14 + modelInfo.cacheReadsPrice = 0.014 + break } models[rawModel.id] = modelInfo @@ -736,7 +1150,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { console.error("Error fetching OpenRouter models:", error) } - await this.postMessageToWebview({ type: "openRouterModels", openRouterModels: models }) + await this.postMessageToWebview({ + type: "openRouterModels", + openRouterModels: models, + }) return models } @@ -779,7 +1196,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { const { historyItem } = await this.getTaskWithId(id) await this.initClineWithHistoryItem(historyItem) // clears existing task } - await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await this.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) } async exportTaskWithId(id: string) { @@ -809,6 +1229,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { if (await fileExistsAtPath(legacyMessagesFilePath)) { await fs.unlink(legacyMessagesFilePath) } + + // Delete the checkpoints directory if it exists + const checkpointsDir = path.join(taskDirPath, "checkpoints") + if (await fileExistsAtPath(checkpointsDir)) { + try { + await fs.rm(checkpointsDir, { recursive: true, force: true }) + } catch (error) { + console.error(`Failed to delete checkpoints directory for task ${id}:`, error) + // Continue with deletion of task directory - don't throw since this is a cleanup operation + } + } + await fs.rmdir(taskDirPath) // succeeds if the dir is empty } @@ -827,18 +1259,34 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.postMessageToWebview({ type: "state", state }) } - async getStateToPostToWebview() { - const { apiConfiguration, lastShownAnnouncementId, customInstructions, taskHistory, autoApprovalSettings } = - await this.getState() + async getStateToPostToWebview(): Promise { + const { + apiConfiguration, + lastShownAnnouncementId, + customInstructions, + taskHistory, + autoApprovalSettings, + browserSettings, + chatSettings, + userInfo, + authToken, + } = await this.getState() + return { version: this.context.extension?.packageJSON?.version ?? "", apiConfiguration, customInstructions, uriScheme: vscode.env.uriScheme, + currentTaskItem: this.cline?.taskId ? (taskHistory || []).find((item) => item.id === this.cline?.taskId) : undefined, + checkpointTrackerErrorMessage: this.cline?.checkpointTrackerErrorMessage, clineMessages: this.cline?.clineMessages || [], taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts), shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId, autoApprovalSettings, + browserSettings, + chatSettings, + isLoggedIn: !!authToken, + userInfo, } } @@ -853,7 +1301,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { Now that we use retainContextWhenHidden, we don't have to store a cache of cline messages in the user's state, but we could to reduce memory footprint in long conversations. - We have to be careful of what state is shared between ClineProvider instances since there could be multiple instances of the extension running at once. For example when we cached cline messages using the same key, two instances of the extension could end up using the same key and overwriting each other's messages. - - Some state does need to be shared between the instances, i.e. the API key--however there doesn't seem to be a good way to notfy the other instances that the API key has changed. + - Some state does need to be shared between the instances, i.e. the API key--however there doesn't seem to be a good way to notify the other instances that the API key has changed. We need to use a unique identifier for each ClineProvider instance's message cache since we could be running several instances of the extension outside of just the sidebar i.e. in editor panels. @@ -916,6 +1364,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, + deepSeekApiKey, + mistralApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -923,6 +1373,16 @@ export class ClineProvider implements vscode.WebviewViewProvider { customInstructions, taskHistory, autoApprovalSettings, + browserSettings, + chatSettings, + vsCodeLmModelSelector, + liteLlmBaseUrl, + liteLlmModelId, + userInfo, + authToken, + previousModeApiProvider, + previousModeModelId, + previousModeModelInfo, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -945,6 +1405,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("anthropicBaseUrl") as Promise, this.getSecret("geminiApiKey") as Promise, this.getSecret("openAiNativeApiKey") as Promise, + this.getSecret("deepSeekApiKey") as Promise, + this.getSecret("mistralApiKey") as Promise, this.getGlobalState("azureApiVersion") as Promise, this.getGlobalState("openRouterModelId") as Promise, this.getGlobalState("openRouterModelInfo") as Promise, @@ -952,6 +1414,16 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("customInstructions") as Promise, this.getGlobalState("taskHistory") as Promise, this.getGlobalState("autoApprovalSettings") as Promise, + this.getGlobalState("browserSettings") as Promise, + this.getGlobalState("chatSettings") as Promise, + this.getGlobalState("vsCodeLmModelSelector") as Promise, + this.getGlobalState("liteLlmBaseUrl") as Promise, + this.getGlobalState("liteLlmModelId") as Promise, + this.getGlobalState("userInfo") as Promise, + this.getSecret("authToken") as Promise, + this.getGlobalState("previousModeApiProvider") as Promise, + this.getGlobalState("previousModeModelId") as Promise, + this.getGlobalState("previousModeModelInfo") as Promise, ]) let apiProvider: ApiProvider @@ -991,14 +1463,26 @@ export class ClineProvider implements vscode.WebviewViewProvider { anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, + deepSeekApiKey, + mistralApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, + vsCodeLmModelSelector, + liteLlmBaseUrl, + liteLlmModelId, }, lastShownAnnouncementId, customInstructions, taskHistory, autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string + browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS, + chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS, + userInfo, + authToken, + previousModeApiProvider, + previousModeModelId, + previousModeModelInfo, } } @@ -1054,7 +1538,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } - private async getSecret(key: SecretKey) { + async getSecret(key: SecretKey) { return await this.context.secrets.get(key) } @@ -1074,6 +1558,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { "openAiApiKey", "geminiApiKey", "openAiNativeApiKey", + "deepSeekApiKey", + "mistralApiKey", + "authToken", ] for (const key of secretKeys) { await this.storeSecret(key, undefined) @@ -1084,6 +1571,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { } vscode.window.showInformationMessage("State reset") await this.postStateToWebview() - await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await this.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) } } diff --git a/src/exports/index.ts b/src/exports/index.ts index 04d26d8c8b..9432f81fa9 100644 --- a/src/exports/index.ts +++ b/src/exports/index.ts @@ -17,7 +17,10 @@ export function createClineAPI(outputChannel: vscode.OutputChannel, sidebarProvi outputChannel.appendLine("Starting new task") await sidebarProvider.clearTask() await sidebarProvider.postStateToWebview() - await sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await sidebarProvider.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) await sidebarProvider.postMessageToWebview({ type: "invoke", invoke: "sendMessage", diff --git a/src/extension.ts b/src/extension.ts index 49e8bbf970..ed9cff31e9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,7 @@ import delay from "delay" import * as vscode from "vscode" import { ClineProvider } from "./core/webview/ClineProvider" +import { Logger } from "./services/logging/Logger" import { createClineAPI } from "./exports" import "./utils/path" // necessary to have access to String.prototype.toPosix import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider" @@ -24,7 +25,8 @@ export function activate(context: vscode.ExtensionContext) { outputChannel = vscode.window.createOutputChannel("Cline") context.subscriptions.push(outputChannel) - outputChannel.appendLine("Cline extension activated") + Logger.initialize(outputChannel) + Logger.log("Cline extension activated") const sidebarProvider = new ClineProvider(context, outputChannel) @@ -36,21 +38,27 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand("cline.plusButtonClicked", async () => { - outputChannel.appendLine("Plus button Clicked") + Logger.log("Plus button Clicked") await sidebarProvider.clearTask() await sidebarProvider.postStateToWebview() - await sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await sidebarProvider.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) }), ) context.subscriptions.push( vscode.commands.registerCommand("cline.mcpButtonClicked", () => { - sidebarProvider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" }) + sidebarProvider.postMessageToWebview({ + type: "action", + action: "mcpButtonClicked", + }) }), ) const openClineInNewTab = async () => { - outputChannel.appendLine("Opening Cline in new tab") + Logger.log("Opening Cline in new tab") // (this example uses webviewProvider activation event which is necessary to deserialize cached webview, but since we use retainContextWhenHidden, we don't need to use that event) // https://github.com/microsoft/vscode-extension-samples/blob/main/webview-sample/src/extension.ts const tabProvider = new ClineProvider(context, outputChannel) @@ -88,13 +96,28 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand("cline.settingsButtonClicked", () => { //vscode.window.showInformationMessage(message) - sidebarProvider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) + sidebarProvider.postMessageToWebview({ + type: "action", + action: "settingsButtonClicked", + }) }), ) context.subscriptions.push( vscode.commands.registerCommand("cline.historyButtonClicked", () => { - sidebarProvider.postMessageToWebview({ type: "action", action: "historyButtonClicked" }) + sidebarProvider.postMessageToWebview({ + type: "action", + action: "historyButtonClicked", + }) + }), + ) + + context.subscriptions.push( + vscode.commands.registerCommand("cline.accountLoginClicked", () => { + sidebarProvider.postMessageToWebview({ + type: "action", + action: "accountLoginClicked", + }) }), ) @@ -110,12 +133,16 @@ export function activate(context: vscode.ExtensionContext) { return Buffer.from(uri.query, "base64").toString("utf-8") } })() - context.subscriptions.push( - vscode.workspace.registerTextDocumentContentProvider(DIFF_VIEW_URI_SCHEME, diffContentProvider), - ) + context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(DIFF_VIEW_URI_SCHEME, diffContentProvider)) // URI Handler const handleUri = async (uri: vscode.Uri) => { + console.log("URI Handler called with:", { + path: uri.path, + query: uri.query, + scheme: uri.scheme, + }) + const path = uri.path const query = new URLSearchParams(uri.query.replace(/\+/g, "%2B")) const visibleProvider = ClineProvider.getVisibleInstance() @@ -130,6 +157,26 @@ export function activate(context: vscode.ExtensionContext) { } break } + case "/auth": { + const token = query.get("token") + const state = query.get("state") + + console.log("Auth callback received:", { + token: token, + state: state, + }) + + // Validate state parameter + if (!(await visibleProvider.validateAuthState(state))) { + vscode.window.showErrorMessage("Invalid auth state") + return + } + + if (token) { + await visibleProvider.handleAuthCallback(token) + } + break + } default: break } @@ -141,5 +188,5 @@ export function activate(context: vscode.ExtensionContext) { // This method is called when your extension is deactivated export function deactivate() { - outputChannel.appendLine("Cline extension deactivated") + Logger.log("Cline extension deactivated") } diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts new file mode 100644 index 0000000000..75758e8d63 --- /dev/null +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -0,0 +1,420 @@ +import fs from "fs/promises" +import os from "os" +import * as path from "path" +import simpleGit, { SimpleGit } from "simple-git" +import * as vscode from "vscode" +import { ClineProvider } from "../../core/webview/ClineProvider" +import { fileExistsAtPath } from "../../utils/fs" +import { globby } from "globby" + +class CheckpointTracker { + private providerRef: WeakRef + private taskId: string + private disposables: vscode.Disposable[] = [] + private cwd: string + private lastRetrievedShadowGitConfigWorkTree?: string + lastCheckpointHash?: string + + private constructor(provider: ClineProvider, taskId: string, cwd: string) { + this.providerRef = new WeakRef(provider) + this.taskId = taskId + this.cwd = cwd + } + + public static async create(taskId: string, provider?: ClineProvider): Promise { + try { + if (!provider) { + throw new Error("Provider is required to create a checkpoint tracker") + } + + // Check if checkpoints are disabled in VS Code settings + const enableCheckpoints = vscode.workspace.getConfiguration("cline").get("enableCheckpoints") ?? true + if (!enableCheckpoints) { + return undefined // Don't create tracker when disabled + } + + // Check if git is installed by attempting to get version + try { + await simpleGit().version() + } catch (error) { + throw new Error("Git must be installed to use checkpoints.") // FIXME: must match what we check for in TaskHeader to show link + } + + const cwd = await CheckpointTracker.getWorkingDirectory() + const newTracker = new CheckpointTracker(provider, taskId, cwd) + await newTracker.initShadowGit() + return newTracker + } catch (error) { + console.error("Failed to create CheckpointTracker:", error) + throw error + } + } + + private static async getWorkingDirectory(): Promise { + const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) + if (!cwd) { + throw new Error("No workspace detected. Please open Cline in a workspace to use checkpoints.") + } + const homedir = os.homedir() + const desktopPath = path.join(homedir, "Desktop") + const documentsPath = path.join(homedir, "Documents") + const downloadsPath = path.join(homedir, "Downloads") + + switch (cwd) { + case homedir: + throw new Error("Cannot use checkpoints in home directory") + case desktopPath: + throw new Error("Cannot use checkpoints in Desktop directory") + case documentsPath: + throw new Error("Cannot use checkpoints in Documents directory") + case downloadsPath: + throw new Error("Cannot use checkpoints in Downloads directory") + default: + return cwd + } + } + + private async getShadowGitPath(): Promise { + const globalStoragePath = this.providerRef.deref()?.context.globalStorageUri.fsPath + if (!globalStoragePath) { + throw new Error("Global storage uri is invalid") + } + const checkpointsDir = path.join(globalStoragePath, "tasks", this.taskId, "checkpoints") + await fs.mkdir(checkpointsDir, { recursive: true }) + const gitPath = path.join(checkpointsDir, ".git") + return gitPath + } + + public static async doesShadowGitExist(taskId: string, provider?: ClineProvider): Promise { + const globalStoragePath = provider?.context.globalStorageUri.fsPath + if (!globalStoragePath) { + return false + } + const gitPath = path.join(globalStoragePath, "tasks", taskId, "checkpoints", ".git") + return await fileExistsAtPath(gitPath) + } + + public async initShadowGit(): Promise { + const gitPath = await this.getShadowGitPath() + if (await fileExistsAtPath(gitPath)) { + // Make sure it's the same cwd as the configured worktree + const worktree = await this.getShadowGitConfigWorkTree() + if (worktree !== this.cwd) { + throw new Error("Checkpoints can only be used in the original workspace: " + worktree) + } + + return gitPath + } else { + const checkpointsDir = path.dirname(gitPath) + const git = simpleGit(checkpointsDir) + await git.init() + + await git.addConfig("core.worktree", this.cwd) // sets the working tree to the current workspace + + // Disable commit signing for shadow repo + await git.addConfig("commit.gpgSign", "false") + + // Get LFS patterns from workspace if they exist + let lfsPatterns: string[] = [] + try { + const attributesPath = path.join(this.cwd, ".gitattributes") + if (await fileExistsAtPath(attributesPath)) { + const attributesContent = await fs.readFile(attributesPath, "utf8") + lfsPatterns = attributesContent + .split("\n") + .filter((line) => line.includes("filter=lfs")) + .map((line) => line.split(" ")[0].trim()) + } + } catch (error) { + console.warn("Failed to read .gitattributes:", error) + } + + // Add basic excludes directly in git config, while respecting any .gitignore in the workspace + // .git/info/exclude is local to the shadow git repo, so it's not shared with the main repo - and won't conflict with user's .gitignore + // TODO: let user customize these + const excludesPath = path.join(gitPath, "info", "exclude") + await fs.mkdir(path.join(gitPath, "info"), { recursive: true }) + await fs.writeFile( + excludesPath, + [ + ".git/", // ignore the user's .git + `.git${GIT_DISABLED_SUFFIX}/`, // ignore the disabled nested git repos + ".DS_Store", + "*.log", + "node_modules/", + "__pycache__/", + "env/", + "venv/", + "target/dependency/", + "build/dependencies/", + "dist/", + "out/", + "bundle/", + "vendor/", + "tmp/", + "temp/", + "deps/", + "pkg/", + "Pods/", + // Media files + "*.jpg", + "*.jpeg", + "*.png", + "*.gif", + "*.bmp", + "*.ico", + // "*.svg", + "*.mp3", + "*.mp4", + "*.wav", + "*.avi", + "*.mov", + "*.wmv", + "*.webm", + "*.webp", + "*.m4a", + "*.flac", + // Build and dependency directories + "build/", + "bin/", + "obj/", + ".gradle/", + ".idea/", + ".vscode/", + ".vs/", + "coverage/", + ".next/", + ".nuxt/", + // Cache and temporary files + "*.cache", + "*.tmp", + "*.temp", + "*.swp", + "*.swo", + "*.pyc", + "*.pyo", + ".pytest_cache/", + ".eslintcache", + // Environment and config files + ".env*", + "*.local", + "*.development", + "*.production", + // Large data files + "*.zip", + "*.tar", + "*.gz", + "*.rar", + "*.7z", + "*.iso", + "*.bin", + "*.exe", + "*.dll", + "*.so", + "*.dylib", + // Database files + "*.sqlite", + "*.db", + "*.sql", + // Log files + "*.logs", + "*.error", + "npm-debug.log*", + "yarn-debug.log*", + "yarn-error.log*", + ...lfsPatterns, + ].join("\n"), + ) + + // Set up git identity (git throws an error if user.name or user.email is not set) + await git.addConfig("user.name", "Cline Checkpoint") + await git.addConfig("user.email", "noreply@example.com") + + await this.addAllFiles(git) + // Initial commit (--allow-empty ensures it works even with no files) + await git.commit("initial commit", { "--allow-empty": null }) + + return gitPath + } + } + + public async getShadowGitConfigWorkTree(): Promise { + if (this.lastRetrievedShadowGitConfigWorkTree) { + return this.lastRetrievedShadowGitConfigWorkTree + } + try { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + const worktree = await git.getConfig("core.worktree") + this.lastRetrievedShadowGitConfigWorkTree = worktree.value || undefined + return this.lastRetrievedShadowGitConfigWorkTree + } catch (error) { + console.error("Failed to get shadow git config worktree:", error) + return undefined + } + } + + public async commit(): Promise { + try { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + await this.addAllFiles(git) + const result = await git.commit("checkpoint", { + "--allow-empty": null, + }) + const commitHash = result.commit || "" + this.lastCheckpointHash = commitHash + return commitHash + } catch (error) { + console.error("Failed to create checkpoint:", error) + return undefined + } + } + + public async resetHead(commitHash: string): Promise { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + + // Clean working directory and force reset + // This ensures that the operation will succeed regardless of: + // - Untracked files in the workspace + // - Staged changes + // - Unstaged changes + // - Partial commits + // - Merge conflicts + await git.clean("f", ["-d", "-f"]) // Remove untracked files and directories + await git.reset(["--hard", commitHash]) // Hard reset to target commit + } + + /** + * Return an array describing changed files between one commit and either: + * - another commit, or + * - the current working directory (including uncommitted changes). + * + * If `rhsHash` is omitted, compares `lhsHash` to the working directory. + * If you want truly untracked files to appear, `git add` them first. + * + * @param lhsHash - The commit to compare from (older commit) + * @param rhsHash - The commit to compare to (newer commit). + * If omitted, we compare to the working directory. + * @returns Array of file changes with before/after content + */ + public async getDiffSet( + lhsHash?: string, + rhsHash?: string, + ): Promise< + Array<{ + relativePath: string + absolutePath: string + before: string + after: string + }> + > { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + + // If lhsHash is missing, use the initial commit of the repo + let baseHash = lhsHash + if (!baseHash) { + const rootCommit = await git.raw(["rev-list", "--max-parents=0", "HEAD"]) + baseHash = rootCommit.trim() + } + + // Stage all changes so that untracked files appear in diff summary + await this.addAllFiles(git) + + const diffSummary = rhsHash ? await git.diffSummary([`${baseHash}..${rhsHash}`]) : await git.diffSummary([baseHash]) + + // For each changed file, gather before/after content + const result = [] + const cwdPath = (await this.getShadowGitConfigWorkTree()) || this.cwd || "" + + for (const file of diffSummary.files) { + const filePath = file.file + const absolutePath = path.join(cwdPath, filePath) + + let beforeContent = "" + try { + beforeContent = await git.show([`${baseHash}:${filePath}`]) + } catch (_) { + // file didn't exist in older commit => remains empty + } + + let afterContent = "" + if (rhsHash) { + // if user provided a newer commit, use git.show at that commit + try { + afterContent = await git.show([`${rhsHash}:${filePath}`]) + } catch (_) { + // file didn't exist in newer commit => remains empty + } + } else { + // otherwise, read from disk (includes uncommitted changes) + try { + afterContent = await fs.readFile(absolutePath, "utf8") + } catch (_) { + // file might be deleted => remains empty + } + } + + result.push({ + relativePath: filePath, + absolutePath, + before: beforeContent, + after: afterContent, + }) + } + + return result + } + + private async addAllFiles(git: SimpleGit) { + await this.renameNestedGitRepos(true) + try { + await git.add(".") + } catch (error) { + console.error("Failed to add files to git:", error) + } finally { + await this.renameNestedGitRepos(false) + } + } + + // Since we use git to track checkpoints, we need to temporarily disable nested git repos to work around git's requirement of using submodules for nested repos. + private async renameNestedGitRepos(disable: boolean) { + // Find all .git directories that are not at the root level + const gitPaths = await globby("**/.git" + (disable ? "" : GIT_DISABLED_SUFFIX), { + cwd: this.cwd, + onlyDirectories: true, + ignore: [".git"], // Ignore root level .git + dot: true, + markDirectories: false, + }) + + // For each nested .git directory, rename it based on operation + for (const gitPath of gitPaths) { + const fullPath = path.join(this.cwd, gitPath) + let newPath: string + if (disable) { + newPath = fullPath + GIT_DISABLED_SUFFIX + } else { + newPath = fullPath.endsWith(GIT_DISABLED_SUFFIX) ? fullPath.slice(0, -GIT_DISABLED_SUFFIX.length) : fullPath + } + + try { + await fs.rename(fullPath, newPath) + console.log(`CheckpointTracker ${disable ? "disabled" : "enabled"} nested git repo ${gitPath}`) + } catch (error) { + console.error(`CheckpointTracker failed to ${disable ? "disable" : "enable"} nested git repo ${gitPath}:`, error) + } + } + } + + public dispose() { + this.disposables.forEach((d) => d.dispose()) + this.disposables = [] + } +} + +const GIT_DISABLED_SUFFIX = "_disabled" + +export default CheckpointTracker diff --git a/src/integrations/debug/DebugConsoleManager.ts b/src/integrations/debug/DebugConsoleManager.ts new file mode 100644 index 0000000000..43dd476bd2 --- /dev/null +++ b/src/integrations/debug/DebugConsoleManager.ts @@ -0,0 +1,75 @@ +import * as vscode from "vscode" + +interface DebugSession { + id: string + name: string + output: string[] + lastRetrievedIndex: number +} + +export class DebugConsoleManager { + private sessions: Map = new Map() + private disposables: vscode.Disposable[] = [] + + constructor() { + // Listen for debug session start events + this.disposables.push( + vscode.debug.onDidStartDebugSession((session) => { + this.sessions.set(session.id, { + id: session.id, + name: session.name, + output: [], + lastRetrievedIndex: -1, + }) + }), + ) + + // Listen for debug session end events + this.disposables.push( + vscode.debug.onDidTerminateDebugSession((session) => { + this.sessions.delete(session.id) + }), + ) + + // Listen for debug console output + this.disposables.push( + vscode.debug.onDidReceiveDebugSessionCustomEvent((e: vscode.DebugSessionCustomEvent) => { + if (e.event === "output" && e.body?.output) { + const session = this.sessions.get(e.session.id) + if (session) { + session.output.push(e.body.output) + } + } + }), + ) + } + + /** + * Get all active debug sessions + */ + getActiveSessions(): { id: string; name: string }[] { + return Array.from(this.sessions.values()).map(({ id, name }) => ({ id, name })) + } + + /** + * Get any new output since the last retrieval for a specific debug session + */ + getUnretrievedOutput(sessionId: string): string | undefined { + const session = this.sessions.get(sessionId) + if (!session) { + return undefined + } + + const newOutput = session.output.slice(session.lastRetrievedIndex + 1).join("") + session.lastRetrievedIndex = session.output.length - 1 + return newOutput || undefined + } + + /** + * Clean up resources + */ + dispose() { + this.disposables.forEach((d) => d.dispose()) + this.sessions.clear() + } +} diff --git a/src/integrations/editor/DecorationController.ts b/src/integrations/editor/DecorationController.ts index 8f475408d4..6622131e13 100644 --- a/src/integrations/editor/DecorationController.ts +++ b/src/integrations/editor/DecorationController.ts @@ -63,10 +63,7 @@ export class DecorationController { // Add a new range for all lines after the current line if (line < totalLines - 1) { this.ranges.push( - new vscode.Range( - new vscode.Position(line + 1, 0), - new vscode.Position(totalLines - 1, Number.MAX_SAFE_INTEGER), - ), + new vscode.Range(new vscode.Position(line + 1, 0), new vscode.Position(totalLines - 1, Number.MAX_SAFE_INTEGER)), ) } diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 5eb6a56b8f..e416f99de6 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -33,9 +33,7 @@ export class DiffViewProvider { this.isEditing = true // if the file is already open, ensure it's not dirty before getting its contents if (fileExists) { - const existingDocument = vscode.workspace.textDocuments.find((doc) => - arePathsEqual(doc.uri.fsPath, absolutePath), - ) + const existingDocument = vscode.workspace.textDocuments.find((doc) => arePathsEqual(doc.uri.fsPath, absolutePath)) if (existingDocument && existingDocument.isDirty) { await existingDocument.save() } @@ -61,9 +59,7 @@ export class DiffViewProvider { const tabs = vscode.window.tabGroups.all .map((tg) => tg.tabs) .flat() - .filter( - (tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath), - ) + .filter((tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)) for (const tab of tabs) { if (!tab.isDirty) { await vscode.window.tabGroups.close(tab) @@ -141,10 +137,16 @@ export class DiffViewProvider { async saveChanges(): Promise<{ newProblemsMessage: string | undefined userEdits: string | undefined + autoFormattingEdits: string | undefined finalContent: string | undefined }> { if (!this.relPath || !this.newContent || !this.activeDiffEditor) { - return { newProblemsMessage: undefined, userEdits: undefined, finalContent: undefined } + return { + newProblemsMessage: undefined, + userEdits: undefined, + autoFormattingEdits: undefined, + finalContent: undefined, + } } const absolutePath = path.resolve(this.cwd, this.relPath) const updatedDocument = this.activeDiffEditor.document @@ -160,7 +162,9 @@ export class DiffViewProvider { // get text after save in case there is any auto-formatting done by the editor const postSaveContent = updatedDocument.getText() - await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { preview: false }) + await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { + preview: false, + }) await this.closeAllDiffViews() /* @@ -197,17 +201,32 @@ export class DiffViewProvider { const normalizedPostSaveContent = postSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL // this is the final content we return to the model to use as the new baseline for future edits // just in case the new content has a mix of varying EOL characters const normalizedNewContent = this.newContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL + + let userEdits: string | undefined if (normalizedPreSaveContent !== normalizedNewContent) { // user made changes before approving edit. let the model know about user made changes (not including post-save auto-formatting changes) - const userEdits = formatResponse.createPrettyPatch( - this.relPath.toPosix(), - normalizedNewContent, - normalizedPreSaveContent, - ) - return { newProblemsMessage, userEdits, finalContent: normalizedPostSaveContent } + userEdits = formatResponse.createPrettyPatch(this.relPath.toPosix(), normalizedNewContent, normalizedPreSaveContent) + // return { newProblemsMessage, userEdits, finalContent: normalizedPostSaveContent } } else { // no changes to cline's edits - return { newProblemsMessage, userEdits: undefined, finalContent: normalizedPostSaveContent } + // return { newProblemsMessage, userEdits: undefined, finalContent: normalizedPostSaveContent } + } + + let autoFormattingEdits: string | undefined + if (normalizedPreSaveContent !== normalizedPostSaveContent) { + // auto-formatting was done by the editor + autoFormattingEdits = formatResponse.createPrettyPatch( + this.relPath.toPosix(), + normalizedPreSaveContent, + normalizedPostSaveContent, + ) + } + + return { + newProblemsMessage, + userEdits, + autoFormattingEdits, + finalContent: normalizedPostSaveContent, } } @@ -257,11 +276,7 @@ export class DiffViewProvider { private async closeAllDiffViews() { const tabs = vscode.window.tabGroups.all .flatMap((tg) => tg.tabs) - .filter( - (tab) => - tab.input instanceof vscode.TabInputTextDiff && - tab.input?.original?.scheme === DIFF_VIEW_URI_SCHEME, - ) + .filter((tab) => tab.input instanceof vscode.TabInputTextDiff && tab.input?.original?.scheme === DIFF_VIEW_URI_SCHEME) for (const tab of tabs) { // trying to close dirty views results in save popup if (!tab.isDirty) { diff --git a/src/integrations/misc/export-markdown.ts b/src/integrations/misc/export-markdown.ts index 2aa9d7b6ed..76e95e36b7 100644 --- a/src/integrations/misc/export-markdown.ts +++ b/src/integrations/misc/export-markdown.ts @@ -42,11 +42,7 @@ export async function downloadTask(dateTs: number, conversationHistory: Anthropi } export function formatContentBlockToMarkdown( - block: - | Anthropic.TextBlockParam - | Anthropic.ImageBlockParam - | Anthropic.ToolUseBlockParam - | Anthropic.ToolResultBlockParam, + block: Anthropic.TextBlockParam | Anthropic.ImageBlockParam | Anthropic.ToolUseBlockParam | Anthropic.ToolResultBlockParam, // messages: Anthropic.MessageParam[] ): string { switch (block.type) { diff --git a/src/integrations/misc/open-file.ts b/src/integrations/misc/open-file.ts index 8dc3029947..9cd88708d3 100644 --- a/src/integrations/misc/open-file.ts +++ b/src/integrations/misc/open-file.ts @@ -28,14 +28,11 @@ export async function openFile(absolutePath: string) { try { for (const group of vscode.window.tabGroups.all) { const existingTab = group.tabs.find( - (tab) => - tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, uri.fsPath), + (tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, uri.fsPath), ) if (existingTab) { const activeColumn = vscode.window.activeTextEditor?.viewColumn - const tabColumn = vscode.window.tabGroups.all.find((group) => - group.tabs.includes(existingTab), - )?.viewColumn + const tabColumn = vscode.window.tabGroups.all.find((group) => group.tabs.includes(existingTab))?.viewColumn if (activeColumn && activeColumn !== tabColumn && !existingTab.isDirty) { await vscode.window.tabGroups.close(existingTab) } diff --git a/src/integrations/notifications/index.ts b/src/integrations/notifications/index.ts index 88fcc8726a..722df87e32 100644 --- a/src/integrations/notifications/index.ts +++ b/src/integrations/notifications/index.ts @@ -71,15 +71,22 @@ export async function showSystemNotification(options: NotificationOptions): Prom throw new Error("Message is required") } + const escapedOptions = { + ...options, + title: title.replace(/"/g, '\\"'), + message: message.replace(/"/g, '\\"'), + subtitle: options.subtitle?.replace(/"/g, '\\"') || "", + } + switch (platform()) { case "darwin": - await showMacOSNotification({ ...options, title }) + await showMacOSNotification(escapedOptions) break case "win32": - await showWindowsNotification({ ...options, title }) + await showWindowsNotification(escapedOptions) break case "linux": - await showLinuxNotification({ ...options, title }) + await showLinuxNotification(escapedOptions) break default: throw new Error("Unsupported platform") diff --git a/src/integrations/terminal/TerminalManager.ts b/src/integrations/terminal/TerminalManager.ts index 81e91ab6b8..eb640b8c9a 100644 --- a/src/integrations/terminal/TerminalManager.ts +++ b/src/integrations/terminal/TerminalManager.ts @@ -157,8 +157,10 @@ export class TerminalManager { } async getOrCreateTerminal(cwd: string): Promise { + const terminals = TerminalRegistry.getAllTerminals() + // Find available terminal from our pool first (created for this task) - const availableTerminal = TerminalRegistry.getAllTerminals().find((t) => { + const matchingTerminal = terminals.find((t) => { if (t.busy) { return false } @@ -168,11 +170,21 @@ export class TerminalManager { } return arePathsEqual(vscode.Uri.file(cwd).fsPath, terminalCwd.fsPath) }) + if (matchingTerminal) { + this.terminalIds.add(matchingTerminal.id) + return matchingTerminal + } + + // If no matching terminal exists, try to find any non-busy terminal + const availableTerminal = terminals.find((t) => !t.busy) if (availableTerminal) { + // Navigate back to the desired directory + await this.runCommand(availableTerminal, `cd "${cwd}"`) this.terminalIds.add(availableTerminal.id) return availableTerminal } + // If all terminals are busy, create a new one const newTerminalInfo = TerminalRegistry.createTerminal(cwd) this.terminalIds.add(newTerminalInfo.id) return newTerminalInfo diff --git a/src/integrations/theme/default-themes/dark_vs.json b/src/integrations/theme/default-themes/dark_vs.json index e2f078182d..2abaefadfc 100644 --- a/src/integrations/theme/default-themes/dark_vs.json +++ b/src/integrations/theme/default-themes/dark_vs.json @@ -364,11 +364,7 @@ }, { "name": "coloring of the Java import and package identifiers", - "scope": [ - "storage.modifier.import.java", - "variable.language.wildcard.java", - "storage.modifier.package.java" - ], + "scope": ["storage.modifier.import.java", "variable.language.wildcard.java", "storage.modifier.package.java"], "settings": { "foreground": "#d4d4d4" } diff --git a/src/integrations/theme/default-themes/hc_black.json b/src/integrations/theme/default-themes/hc_black.json index b446ebc4c4..b88b869d47 100644 --- a/src/integrations/theme/default-themes/hc_black.json +++ b/src/integrations/theme/default-themes/hc_black.json @@ -57,12 +57,7 @@ } }, { - "scope": [ - "constant.numeric", - "constant.other.color.rgb-value", - "constant.other.rgb-value", - "support.constant.color" - ], + "scope": ["constant.numeric", "constant.other.color.rgb-value", "constant.other.rgb-value", "support.constant.color"], "settings": { "foreground": "#b5cea8" } @@ -320,11 +315,7 @@ }, { "name": "coloring of the Java import and package identifiers", - "scope": [ - "storage.modifier.import.java", - "variable.language.wildcard.java", - "storage.modifier.package.java" - ], + "scope": ["storage.modifier.import.java", "variable.language.wildcard.java", "storage.modifier.package.java"], "settings": { "foreground": "#d4d4d4" } diff --git a/src/integrations/theme/default-themes/hc_light.json b/src/integrations/theme/default-themes/hc_light.json index 1abecd39d7..5310173d9c 100644 --- a/src/integrations/theme/default-themes/hc_light.json +++ b/src/integrations/theme/default-themes/hc_light.json @@ -346,11 +346,7 @@ } }, { - "scope": [ - "storage.modifier.import.java", - "variable.language.wildcard.java", - "storage.modifier.package.java" - ], + "scope": ["storage.modifier.import.java", "variable.language.wildcard.java", "storage.modifier.package.java"], "settings": { "foreground": "#000000" } diff --git a/src/integrations/theme/default-themes/light_vs.json b/src/integrations/theme/default-themes/light_vs.json index eb098e393f..f75e0942fb 100644 --- a/src/integrations/theme/default-themes/light_vs.json +++ b/src/integrations/theme/default-themes/light_vs.json @@ -389,11 +389,7 @@ }, { "name": "coloring of the Java import and package identifiers", - "scope": [ - "storage.modifier.import.java", - "variable.language.wildcard.java", - "storage.modifier.package.java" - ], + "scope": ["storage.modifier.import.java", "variable.language.wildcard.java", "storage.modifier.package.java"], "settings": { "foreground": "#000000" } diff --git a/src/integrations/theme/getTheme.ts b/src/integrations/theme/getTheme.ts index ffed26e462..a5d4493b3d 100644 --- a/src/integrations/theme/getTheme.ts +++ b/src/integrations/theme/getTheme.ts @@ -74,11 +74,7 @@ export async function getTheme() { const converted = convertTheme(parsed) converted.base = ( - ["vs", "hc-black"].includes(converted.base) - ? converted.base - : colorTheme.includes("Light") - ? "vs" - : "vs-dark" + ["vs", "hc-black"].includes(converted.base) ? converted.base : colorTheme.includes("Light") ? "vs" : "vs-dark" ) as any return converted diff --git a/src/integrations/workspace/WorkspaceTracker.ts b/src/integrations/workspace/WorkspaceTracker.ts index 1305e84ec5..10dfac8f9e 100644 --- a/src/integrations/workspace/WorkspaceTracker.ts +++ b/src/integrations/workspace/WorkspaceTracker.ts @@ -27,25 +27,58 @@ class WorkspaceTracker { } private registerListeners() { - const watcher = vscode.workspace.createFileSystemWatcher("**") + // Listen for file creation + // .bind(this) ensures the callback refers to class instance when using this, not necessary when using arrow function + this.disposables.push(vscode.workspace.onDidCreateFiles(this.onFilesCreated.bind(this))) - this.disposables.push( - watcher.onDidCreate(async (uri) => { - await this.addFilePath(uri.fsPath) - this.workspaceDidUpdate() + // Listen for file deletion + this.disposables.push(vscode.workspace.onDidDeleteFiles(this.onFilesDeleted.bind(this))) + + // Listen for file renaming + this.disposables.push(vscode.workspace.onDidRenameFiles(this.onFilesRenamed.bind(this))) + + /* + An event that is emitted when a workspace folder is added or removed. + **Note:** this event will not fire if the first workspace folder is added, removed or changed, + because in that case the currently executing extensions (including the one that listens to this + event) will be terminated and restarted so that the (deprecated) `rootPath` property is updated + to point to the first workspace folder. + */ + // In other words, we don't have to worry about the root workspace folder ([0]) changing since the extension will be restarted and our cwd will be updated to reflect the new workspace folder. (We don't care about non root workspace folders, since cline will only be working within the root folder cwd) + // this.disposables.push(vscode.workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged.bind(this))) + } + + private async onFilesCreated(event: vscode.FileCreateEvent) { + await Promise.all( + event.files.map(async (file) => { + await this.addFilePath(file.fsPath) }), ) + this.workspaceDidUpdate() + } - // Renaming files triggers a delete and create event - this.disposables.push( - watcher.onDidDelete(async (uri) => { - if (await this.removeFilePath(uri.fsPath)) { - this.workspaceDidUpdate() + private async onFilesDeleted(event: vscode.FileDeleteEvent) { + let updated = false + await Promise.all( + event.files.map(async (file) => { + if (await this.removeFilePath(file.fsPath)) { + updated = true } }), ) + if (updated) { + this.workspaceDidUpdate() + } + } - this.disposables.push(watcher) + private async onFilesRenamed(event: vscode.FileRenameEvent) { + await Promise.all( + event.files.map(async (file) => { + await this.removeFilePath(file.oldUri.fsPath) + await this.addFilePath(file.newUri.fsPath) + }), + ) + this.workspaceDidUpdate() } private workspaceDidUpdate() { diff --git a/src/services/auth/FirebaseAuthManager.ts b/src/services/auth/FirebaseAuthManager.ts new file mode 100644 index 0000000000..835a84c0c0 --- /dev/null +++ b/src/services/auth/FirebaseAuthManager.ts @@ -0,0 +1,99 @@ +import { initializeApp } from "firebase/app" +import { Auth, User, getAuth, onAuthStateChanged, signInWithCustomToken, signOut } from "firebase/auth" +import * as vscode from "vscode" +import { ClineProvider } from "../../core/webview/ClineProvider" +import { firebaseConfig } from "./config" + +export interface UserInfo { + displayName: string | null + email: string | null + photoURL: string | null +} + +export class FirebaseAuthManager { + private providerRef: WeakRef + private auth: Auth + private disposables: vscode.Disposable[] = [] + + constructor(provider: ClineProvider) { + console.log("Initializing FirebaseAuthManager", { provider }) + this.providerRef = new WeakRef(provider) + const app = initializeApp(firebaseConfig) + this.auth = getAuth(app) + console.log("Firebase app initialized", { appConfig: firebaseConfig }) + + // Auth state listener + onAuthStateChanged(this.auth, this.handleAuthStateChange.bind(this)) + console.log("Auth state change listener added") + + // Try to restore session + this.restoreSession() + } + + private async restoreSession() { + console.log("Attempting to restore session") + const provider = this.providerRef.deref() + if (!provider) { + console.log("Provider reference lost during session restore") + return + } + + const storedToken = await provider.getSecret("authToken") + if (storedToken) { + console.log("Found stored auth token, attempting to restore session") + try { + await this.signInWithCustomToken(storedToken) + console.log("Session restored successfully") + } catch (error) { + console.error("Failed to restore session, clearing token:", error) + await provider.setAuthToken(undefined) + await provider.setUserInfo(undefined) + } + } else { + console.log("No stored auth token found") + } + } + + private async handleAuthStateChange(user: User | null) { + console.log("Auth state changed", { user }) + const provider = this.providerRef.deref() + if (!provider) { + console.log("Provider reference lost") + return + } + + if (user) { + console.log("User signed in", { userId: user.uid }) + const idToken = await user.getIdToken() + await provider.setAuthToken(idToken) + // Store public user info in state + await provider.setUserInfo({ + displayName: user.displayName, + email: user.email, + photoURL: user.photoURL, + }) + console.log("User info set in provider", { user }) + } else { + console.log("User signed out") + await provider.setAuthToken(undefined) + await provider.setUserInfo(undefined) + } + await provider.postStateToWebview() + console.log("Webview state updated") + } + + async signInWithCustomToken(token: string) { + console.log("Signing in with custom token", { token }) + await signInWithCustomToken(this.auth, token) + } + + async signOut() { + console.log("Signing out") + await signOut(this.auth) + } + + dispose() { + this.disposables.forEach((d) => d.dispose()) + console.log("Disposables disposed", { count: this.disposables.length }) + } +} diff --git a/src/services/auth/config.ts b/src/services/auth/config.ts new file mode 100644 index 0000000000..86034075a2 --- /dev/null +++ b/src/services/auth/config.ts @@ -0,0 +1,10 @@ +// Public Firebase config (safe for open source) +export const firebaseConfig = { + apiKey: "AIzaSyDcXAaanNgR2_T0dq2oOl5XyKPksYHppVo", + authDomain: "cline-bot.firebaseapp.com", + projectId: "cline-bot", + storageBucket: "cline-bot.firebasestorage.app", + messagingSenderId: "364369702101", + appId: "1:364369702101:web:0013885dcf20b43799c65c", + measurementId: "G-MDPRELSCD1", +} diff --git a/src/services/browser/BrowserSession.ts b/src/services/browser/BrowserSession.ts index b45265c77b..cbc7734d36 100644 --- a/src/services/browser/BrowserSession.ts +++ b/src/services/browser/BrowserSession.ts @@ -8,20 +8,26 @@ import pWaitFor from "p-wait-for" import delay from "delay" import { fileExistsAtPath } from "../../utils/fs" import { BrowserActionResult } from "../../shared/ExtensionMessage" +import { BrowserSettings } from "../../shared/BrowserSettings" +// import * as chromeLauncher from "chrome-launcher" interface PCRStats { puppeteer: { launch: typeof launch } executablePath: string } +// const DEBUG_PORT = 9222 // Chrome's default debugging port + export class BrowserSession { private context: vscode.ExtensionContext private browser?: Browser private page?: Page private currentMousePosition?: string + browserSettings: BrowserSettings - constructor(context: vscode.ExtensionContext) { + constructor(context: vscode.ExtensionContext, browserSettings: BrowserSettings) { this.context = context + this.browserSettings = browserSettings } private async ensureChromiumExists(): Promise { @@ -45,6 +51,70 @@ export class BrowserSession { return stats } + // private async checkExistingChromeDebugger(): Promise { + // try { + // // Try to connect to existing debugger + // const response = await fetch(`http://localhost:${DEBUG_PORT}/json/version`) + // return response.ok + // } catch { + // return false + // } + // } + + // async relaunchChromeDebugMode() { + // const result = await vscode.window.showWarningMessage( + // "This will close your existing Chrome tabs and relaunch Chrome in debug mode. Are you sure?", + // { modal: true }, + // "Yes", + // ) + + // if (result !== "Yes") { + // return + // } + + // // // Kill any existing Chrome instances + // // await chromeLauncher.killAll() + + // // // Launch Chrome with debug port + // // const launcher = new chromeLauncher.Launcher({ + // // port: DEBUG_PORT, + // // chromeFlags: ["--remote-debugging-port=" + DEBUG_PORT, "--no-first-run", "--no-default-browser-check"], + // // }) + + // // await launcher.launch() + // const installation = chromeLauncher.Launcher.getFirstInstallation() + // if (!installation) { + // throw new Error("Could not find Chrome installation on this system") + // } + // console.log("chrome installation", installation) + // } + + // private async getSystemChromeExecutablePath(): Promise { + // // Find installed Chrome + // const installation = chromeLauncher.Launcher.getFirstInstallation() + // if (!installation) { + // throw new Error("Could not find Chrome installation on this system") + // } + // console.log("chrome installation", installation) + // return installation + // } + + // /** + // * Helper to detect user’s default Chrome data dir. + // * Adjust for OS if needed. + // */ + // private getDefaultChromeUserDataDir(): string { + // const homedir = require("os").homedir() + // switch (process.platform) { + // case "win32": + // return path.join(homedir, "AppData", "Local", "Google", "Chrome", "User Data") + // case "darwin": + // return path.join(homedir, "Library", "Application Support", "Google", "Chrome") + // default: + // return path.join(homedir, ".config", "google-chrome") + // } + // } + async launchBrowser() { console.log("launch browser called") if (this.browser) { @@ -58,12 +128,29 @@ export class BrowserSession { "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", ], executablePath: stats.executablePath, - defaultViewport: { - width: 900, - height: 600, - }, - // headless: false, + defaultViewport: this.browserSettings.viewport, + headless: this.browserSettings.headless, }) + + // if (this.browserSettings.chromeType === "system") { + // const userDataDir = this.getDefaultChromeUserDataDir() + // this.browser = await stats.puppeteer.launch({ + // args: [`--user-data-dir=${userDataDir}`, "--profile-directory=Default"], + // executablePath: await this.getSystemChromeExecutablePath(), + // defaultViewport: this.browserSettings.viewport, + // headless: this.browserSettings.headless, + // }) + // } else { + // this.browser = await stats.puppeteer.launch({ + // args: [ + // "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", + // ], + // executablePath: stats.executablePath, + // defaultViewport: this.browserSettings.viewport, + // headless: this.browserSettings.headless, + // }) + // } + // (latest version of puppeteer does not add headless to user agent) this.page = await this.browser?.newPage() } @@ -166,7 +253,10 @@ export class BrowserSession { async navigateToUrl(url: string): Promise { return this.doAction(async (page) => { // networkidle2 isn't good enough since page may take some time to load. we can assume locally running dev sites will reach networkidle0 in a reasonable amount of time - await page.goto(url, { timeout: 7_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + await page.goto(url, { + timeout: 7_000, + waitUntil: ["domcontentloaded", "networkidle2"], + }) // await page.goto(url, { timeout: 10_000, waitUntil: "load" }) await this.waitTillHTMLStable(page) // in case the page is loading more resources }) diff --git a/src/services/browser/UrlContentFetcher.ts b/src/services/browser/UrlContentFetcher.ts index caf19ee83b..614338503e 100644 --- a/src/services/browser/UrlContentFetcher.ts +++ b/src/services/browser/UrlContentFetcher.ts @@ -71,7 +71,10 @@ export class UrlContentFetcher { - domcontentloaded is when the basic DOM is loaded this should be sufficient for most doc sites */ - await this.page.goto(url, { timeout: 10_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + await this.page.goto(url, { + timeout: 10_000, + waitUntil: ["domcontentloaded", "networkidle2"], + }) const content = await this.page.content() // use cheerio to parse and clean up the HTML diff --git a/src/services/llm-access-control/LLMFileAccessController.test.ts b/src/services/llm-access-control/LLMFileAccessController.test.ts new file mode 100644 index 0000000000..8bf6353a48 --- /dev/null +++ b/src/services/llm-access-control/LLMFileAccessController.test.ts @@ -0,0 +1,259 @@ +import { LLMFileAccessController } from "./LLMFileAccessController" +import fs from "fs/promises" +import path from "path" +import os from "os" +import { after, beforeEach, describe, it } from "mocha" +import "should" + +describe("LLMFileAccessController", () => { + let tempDir: string + let controller: LLMFileAccessController + + beforeEach(async () => { + // Create a temp directory for testing + tempDir = path.join(os.tmpdir(), `llm-test-${Date.now()}-${Math.random().toString(36).slice(2)}`) + await fs.mkdir(tempDir) + + // Create default .clineignore file + await fs.writeFile( + path.join(tempDir, ".clineignore"), + [".env", "*.secret", "private/", "# This is a comment", "", "temp.*", "file-with-space-at-end.* ", "**/.git/**"].join( + "\n", + ), + ) + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + }) + + after(async () => { + // Clean up temp directory + await fs.rm(tempDir, { recursive: true, force: true }) + }) + + describe("Default Patterns", () => { + // it("should block access to common ignored files", async () => { + // const results = [ + // controller.validateAccess(".env"), + // controller.validateAccess(".git/config"), + // controller.validateAccess("node_modules/package.json"), + // ] + // results.forEach((result) => result.should.be.false()) + // }) + + it("should allow access to regular files", async () => { + const results = [ + controller.validateAccess("src/index.ts"), + controller.validateAccess("README.md"), + controller.validateAccess("package.json"), + ] + results.forEach((result) => result.should.be.true()) + }) + }) + + describe("Custom Patterns", () => { + it("should block access to custom ignored patterns", async () => { + const results = [ + controller.validateAccess("config.secret"), + controller.validateAccess("private/data.txt"), + controller.validateAccess("temp.json"), + controller.validateAccess("nested/deep/file.secret"), + controller.validateAccess("private/nested/deep/file.txt"), + ] + results.forEach((result) => result.should.be.false()) + }) + + it("should allow access to non-ignored files", async () => { + const results = [ + controller.validateAccess("public/data.txt"), + controller.validateAccess("config.json"), + controller.validateAccess("src/temp/file.ts"), + controller.validateAccess("nested/deep/file.txt"), + controller.validateAccess("not-private/data.txt"), + ] + results.forEach((result) => result.should.be.true()) + }) + + it("should handle pattern edge cases", async () => { + await fs.writeFile( + path.join(tempDir, ".clineignore"), + ["*.secret", "private/", "*.tmp", "data-*.json", "temp/*"].join("\n"), + ) + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + + const results = [ + controller.validateAccess("data-123.json"), // Should be false (wildcard) + controller.validateAccess("data.json"), // Should be true (doesn't match pattern) + controller.validateAccess("script.tmp"), // Should be false (extension match) + ] + + results[0].should.be.false() // data-123.json + results[1].should.be.true() // data.json + results[2].should.be.false() // script.tmp + }) + + // ToDo: handle negation patterns successfully + + // it("should handle negation patterns", async () => { + // await fs.writeFile( + // path.join(tempDir, ".clineignore"), + // [ + // "temp/*", // Ignore everything in temp + // "!temp/allowed/*", // But allow files in temp/allowed + // "docs/**/*.md", // Ignore all markdown files in docs + // "!docs/README.md", // Except README.md + // "!docs/CONTRIBUTING.md", // And CONTRIBUTING.md + // "assets/", // Ignore all assets + // "!assets/public/", // Except public assets + // "!assets/public/*.png", // Specifically allow PNGs in public assets + // ].join("\n"), + // ) + + // controller = new LLMFileAccessController(tempDir) + + // const results = [ + // // Basic negation + // controller.validateAccess("temp/file.txt"), // Should be false (in temp/) + // controller.validateAccess("temp/allowed/file.txt"), // Should be true (negated) + // controller.validateAccess("temp/allowed/nested/file.txt"), // Should be true (negated with nested) + + // // Multiple negations in same path + // controller.validateAccess("docs/guide.md"), // Should be false (matches docs/**/*.md) + // controller.validateAccess("docs/README.md"), // Should be true (negated) + // controller.validateAccess("docs/CONTRIBUTING.md"), // Should be true (negated) + // controller.validateAccess("docs/api/guide.md"), // Should be false (nested markdown) + + // // Nested negations + // controller.validateAccess("assets/logo.png"), // Should be false (in assets/) + // controller.validateAccess("assets/public/logo.png"), // Should be true (negated and matches *.png) + // controller.validateAccess("assets/public/data.json"), // Should be true (in negated public/) + // ] + + // results[0].should.be.false() // temp/file.txt + // results[1].should.be.true() // temp/allowed/file.txt + // results[2].should.be.true() // temp/allowed/nested/file.txt + // results[3].should.be.false() // docs/guide.md + // results[4].should.be.true() // docs/README.md + // results[5].should.be.true() // docs/CONTRIBUTING.md + // results[6].should.be.false() // docs/api/guide.md + // results[7].should.be.false() // assets/logo.png + // results[8].should.be.true() // assets/public/logo.png + // results[9].should.be.true() // assets/public/data.json + // }) + + it("should handle comments in .clineignore", async () => { + // Create a new .clineignore with comments + await fs.writeFile( + path.join(tempDir, ".clineignore"), + ["# Comment line", "*.secret", "private/", "temp.*"].join("\n"), + ) + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + + const result = controller.validateAccess("test.secret") + result.should.be.false() + }) + }) + + describe("Path Handling", () => { + it("should handle absolute paths and match ignore patterns", async () => { + // Test absolute path that should be allowed + const allowedPath = path.join(tempDir, "src/file.ts") + const allowedResult = controller.validateAccess(allowedPath) + allowedResult.should.be.true() + + // Test absolute path that matches an ignore pattern (*.secret) + const ignoredPath = path.join(tempDir, "config.secret") + const ignoredResult = controller.validateAccess(ignoredPath) + ignoredResult.should.be.false() + + // Test absolute path in ignored directory (private/) + const ignoredDirPath = path.join(tempDir, "private/data.txt") + const ignoredDirResult = controller.validateAccess(ignoredDirPath) + ignoredDirResult.should.be.false() + }) + + it("should handle relative paths and match ignore patterns", async () => { + // Test relative path that should be allowed + const allowedResult = controller.validateAccess("./src/file.ts") + allowedResult.should.be.true() + + // Test relative path that matches an ignore pattern (*.secret) + const ignoredResult = controller.validateAccess("./config.secret") + ignoredResult.should.be.false() + + // Test relative path in ignored directory (private/) + const ignoredDirResult = controller.validateAccess("./private/data.txt") + ignoredDirResult.should.be.false() + }) + + it("should normalize paths with backslashes", async () => { + const result = controller.validateAccess("src\\file.ts") + result.should.be.true() + }) + + it("should handle paths outside cwd", async () => { + // Create a path that points to parent directory of cwd + const outsidePath = path.join(path.dirname(tempDir), "outside.txt") + const result = controller.validateAccess(outsidePath) + + // Should return false for security since path is outside cwd + result.should.be.false() + + // Test with a deeply nested path outside cwd + const deepOutsidePath = path.join(path.dirname(tempDir), "deep", "nested", "outside.secret") + const deepResult = controller.validateAccess(deepOutsidePath) + deepResult.should.be.false() + + // Test with a path that tries to escape using ../ + const escapeAttemptPath = path.join(tempDir, "..", "escape-attempt.txt") + const escapeResult = controller.validateAccess(escapeAttemptPath) + escapeResult.should.be.false() + }) + }) + + describe("Batch Filtering", () => { + it("should filter an array of paths", async () => { + const paths = ["src/index.ts", ".env", "lib/utils.ts", ".git/config", "dist/bundle.js"] + + const filtered = controller.filterPaths(paths) + filtered.should.deepEqual(["src/index.ts", "lib/utils.ts", "dist/bundle.js"]) + }) + }) + + describe("Error Handling", () => { + it("should handle invalid paths", async () => { + // Test with an invalid path containing null byte + const result = controller.validateAccess("\0invalid") + result.should.be.true() + }) + + it("should handle missing .clineignore gracefully", async () => { + // Create a new controller in a directory without .clineignore + const emptyDir = path.join(os.tmpdir(), `llm-test-empty-${Date.now()}`) + await fs.mkdir(emptyDir) + + try { + const controller = new LLMFileAccessController(emptyDir) + await controller.initialize() + const result = controller.validateAccess("file.txt") + result.should.be.true() + } finally { + await fs.rm(emptyDir, { recursive: true, force: true }) + } + }) + + it("should handle empty .clineignore", async () => { + await fs.writeFile(path.join(tempDir, ".clineignore"), "") + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + + const result = controller.validateAccess("regular-file.txt") + result.should.be.true() + }) + }) +}) diff --git a/src/services/llm-access-control/LLMFileAccessController.ts b/src/services/llm-access-control/LLMFileAccessController.ts new file mode 100644 index 0000000000..40a2e46b55 --- /dev/null +++ b/src/services/llm-access-control/LLMFileAccessController.ts @@ -0,0 +1,151 @@ +import path from "path" +import { fileExistsAtPath } from "../../utils/fs" +import fs from "fs/promises" +import ignore, { Ignore } from "ignore" +import * as vscode from "vscode" + +/** + * Controls LLM access to files by enforcing ignore patterns. + * Designed to be instantiated once in Cline.ts and passed to file manipulation services. + * Uses the 'ignore' library to support standard .gitignore syntax in .clineignore files. + */ +export class LLMFileAccessController { + private cwd: string + private ignoreInstance: Ignore + private fileWatcher: vscode.FileSystemWatcher | null + private disposables: vscode.Disposable[] = [] + + /** + * Default patterns that are always ignored for security + */ + private static readonly DEFAULT_PATTERNS = [] // empty for now + + constructor(cwd: string) { + this.cwd = cwd + this.ignoreInstance = ignore() + this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS) + this.fileWatcher = null + + // Set up file watcher for .clineignore + this.setupFileWatcher() + } + + /** + * Initialize the controller by loading custom patterns + * Must be called after construction and before using the controller + */ + async initialize(): Promise { + await this.loadCustomPatterns() + } + + /** + * Set up the file watcher for .clineignore changes + */ + private setupFileWatcher(): void { + const clineignorePattern = new vscode.RelativePattern(this.cwd, ".clineignore") + this.fileWatcher = vscode.workspace.createFileSystemWatcher(clineignorePattern) + + // Watch for changes and updates + this.disposables.push( + this.fileWatcher.onDidChange(() => { + this.loadCustomPatterns().catch((error) => { + console.error("Failed to load updated .clineignore patterns:", error) + }) + }), + this.fileWatcher.onDidCreate(() => { + this.loadCustomPatterns().catch((error) => { + console.error("Failed to load new .clineignore patterns:", error) + }) + }), + this.fileWatcher.onDidDelete(() => { + this.resetToDefaultPatterns() + }), + ) + + // Add fileWatcher itself to disposables + this.disposables.push(this.fileWatcher) + } + + /** + * Load custom patterns from .clineignore if it exists + */ + private async loadCustomPatterns(): Promise { + try { + const ignorePath = path.join(this.cwd, ".clineignore") + if (await fileExistsAtPath(ignorePath)) { + // Reset ignore instance to prevent duplicate patterns + this.resetToDefaultPatterns() + const content = await fs.readFile(ignorePath, "utf8") + const customPatterns = content + .split("\n") + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith("#")) + + this.ignoreInstance.add(customPatterns) + } + } catch (error) { + // Continue with default patterns + } + } + + /** + * Reset ignore patterns to defaults + */ + private resetToDefaultPatterns(): void { + this.ignoreInstance = ignore() + this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS) + } + + /** + * Check if a file should be accessible to the LLM + * @param filePath - Path to check (relative to cwd) + * @returns true if file is accessible, false if ignored + */ + validateAccess(filePath: string): boolean { + try { + // Normalize path to be relative to cwd and use forward slashes + const absolutePath = path.resolve(this.cwd, filePath) + const relativePath = path.relative(this.cwd, absolutePath).replace(/\\/g, "/") + + // Block access to paths outside cwd (those starting with '..') + if (relativePath.startsWith("..")) { + return false + } + + // Use ignore library to check if path should be ignored + return !this.ignoreInstance.ignores(relativePath) + } catch (error) { + console.error(`Error validating access for ${filePath}:`, error) + return false // Fail closed for security + } + } + + /** + * Filter an array of paths, removing those that should be ignored + * @param paths - Array of paths to filter (relative to cwd) + * @returns Array of allowed paths + */ + filterPaths(paths: string[]): string[] { + try { + return paths + .map((p) => ({ + path: p, + allowed: this.validateAccess(p), + })) + .filter((x) => x.allowed) + .map((x) => x.path) + } catch (error) { + console.error("Error filtering paths:", error) + return [] // Fail closed for security + } + } + + /** + * Clean up resources when the controller is no longer needed + */ + dispose(): void { + this.disposables.forEach((d) => d.dispose()) + this.disposables = [] + this.fileWatcher = null + } +} diff --git a/src/services/logging/Logger.ts b/src/services/logging/Logger.ts new file mode 100644 index 0000000000..0c94952ae6 --- /dev/null +++ b/src/services/logging/Logger.ts @@ -0,0 +1,18 @@ +import type { OutputChannel } from "vscode" + +/** + * Simple logging utility for the extension's backend code. + * Uses VS Code's OutputChannel which must be initialized from extension.ts + * to ensure proper registration with the extension context. + */ +export class Logger { + private static outputChannel: OutputChannel + + static initialize(outputChannel: OutputChannel) { + Logger.outputChannel = outputChannel + } + + static log(message: string) { + Logger.outputChannel.appendLine(message) + } +} diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 18a4685a9d..9c6fee3a56 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -16,6 +16,7 @@ import * as vscode from "vscode" import { z } from "zod" import { ClineProvider, GlobalFileNames } from "../../core/webview/ClineProvider" import { + McpMode, McpResource, McpResourceResponse, McpResourceTemplate, @@ -32,11 +33,15 @@ export type McpConnection = { transport: StdioClientTransport } +const AutoApproveSchema = z.array(z.string()).default([]) + // StdioServerParameters const StdioConfigSchema = z.object({ command: z.string(), args: z.array(z.string()).optional(), env: z.record(z.string()).optional(), + autoApprove: AutoApproveSchema.optional(), + disabled: z.boolean().optional(), }) const McpSettingsSchema = z.object({ @@ -58,7 +63,12 @@ export class McpHub { } getServers(): McpServer[] { - return this.connections.map((conn) => conn.server) + // Only return enabled servers + return this.connections.filter((conn) => !conn.server.disabled).map((conn) => conn.server) + } + + getMode(): McpMode { + return vscode.workspace.getConfiguration("cline.mcp").get("mode", "full") } async getMcpServersPath(): Promise { @@ -75,10 +85,7 @@ export class McpHub { if (!provider) { throw new Error("Provider not available") } - const mcpSettingsFilePath = path.join( - await provider.ensureSettingsDirectoryExists(), - GlobalFileNames.mcpSettings, - ) + const mcpSettingsFilePath = path.join(await provider.ensureSettingsDirectoryExists(), GlobalFileNames.mcpSettings) const fileExists = await fileExistsAtPath(mcpSettingsFilePath) if (!fileExists) { await fs.writeFile( @@ -199,11 +206,13 @@ export class McpHub { } // valid schema + const parsedConfig = StdioConfigSchema.parse(config) const connection: McpConnection = { server: { name, config: JSON.stringify(config), status: "connecting", + disabled: parsedConfig.disabled, }, client, transport, @@ -285,7 +294,21 @@ export class McpHub { const response = await this.connections .find((conn) => conn.server.name === serverName) ?.client.request({ method: "tools/list" }, ListToolsResultSchema) - return response?.tools || [] + + // Get autoApprove settings + const settingsPath = await this.getMcpSettingsFilePath() + const content = await fs.readFile(settingsPath, "utf-8") + const config = JSON.parse(content) + const autoApproveConfig = config.mcpServers[serverName]?.autoApprove || [] + + // Mark tools as always allowed based on settings + const tools = (response?.tools || []).map((tool) => ({ + ...tool, + autoApprove: autoApproveConfig.includes(tool.name), + })) + + // console.log(`[MCP] Fetched tools for ${serverName}:`, tools) + return tools } catch (error) { // console.error(`Failed to fetch tools for ${serverName}:`, error) return [] @@ -451,11 +474,91 @@ export class McpHub { // Using server + // Public methods for server management + + public async toggleServerDisabled(serverName: string, disabled: boolean): Promise { + let settingsPath: string + try { + settingsPath = await this.getMcpSettingsFilePath() + + // Ensure the settings file exists and is accessible + try { + await fs.access(settingsPath) + } catch (error) { + console.error("Settings file not accessible:", error) + throw new Error("Settings file not accessible") + } + const content = await fs.readFile(settingsPath, "utf-8") + const config = JSON.parse(content) + + // Validate the config structure + if (!config || typeof config !== "object") { + throw new Error("Invalid config structure") + } + + if (!config.mcpServers || typeof config.mcpServers !== "object") { + config.mcpServers = {} + } + + if (config.mcpServers[serverName]) { + // Create a new server config object to ensure clean structure + const serverConfig = { + ...config.mcpServers[serverName], + disabled, + } + + // Ensure required fields exist + if (!serverConfig.autoApprove) { + serverConfig.autoApprove = [] + } + + config.mcpServers[serverName] = serverConfig + + // Write the entire config back + const updatedConfig = { + mcpServers: config.mcpServers, + } + + await fs.writeFile(settingsPath, JSON.stringify(updatedConfig, null, 2)) + + const connection = this.connections.find((conn) => conn.server.name === serverName) + if (connection) { + try { + connection.server.disabled = disabled + + // Only refresh capabilities if connected + if (connection.server.status === "connected") { + connection.server.tools = await this.fetchToolsList(serverName) + connection.server.resources = await this.fetchResourcesList(serverName) + connection.server.resourceTemplates = await this.fetchResourceTemplatesList(serverName) + } + } catch (error) { + console.error(`Failed to refresh capabilities for ${serverName}:`, error) + } + } + + await this.notifyWebviewOfServerChanges() + } + } catch (error) { + console.error("Failed to update server disabled state:", error) + if (error instanceof Error) { + console.error("Error details:", error.message, error.stack) + } + vscode.window.showErrorMessage( + `Failed to update server state: ${error instanceof Error ? error.message : String(error)}`, + ) + throw error + } + } + async readResource(serverName: string, uri: string): Promise { const connection = this.connections.find((conn) => conn.server.name === serverName) if (!connection) { throw new Error(`No connection found for server: ${serverName}`) } + if (connection.server.disabled) { + throw new Error(`Server "${serverName}" is disabled`) + } return await connection.client.request( { method: "resources/read", @@ -467,17 +570,18 @@ export class McpHub { ) } - async callTool( - serverName: string, - toolName: string, - toolArguments?: Record, - ): Promise { + async callTool(serverName: string, toolName: string, toolArguments?: Record): Promise { const connection = this.connections.find((conn) => conn.server.name === serverName) if (!connection) { throw new Error( `No connection found for server: ${serverName}. Please make sure to use MCP servers available under 'Connected MCP Servers'.`, ) } + + if (connection.server.disabled) { + throw new Error(`Server "${serverName}" is disabled and cannot be used`) + } + return await connection.client.request( { method: "tools/call", @@ -490,6 +594,44 @@ export class McpHub { ) } + async toggleToolAutoApprove(serverName: string, toolName: string, shouldAllow: boolean): Promise { + try { + const settingsPath = await this.getMcpSettingsFilePath() + const content = await fs.readFile(settingsPath, "utf-8") + const config = JSON.parse(content) + + // Initialize autoApprove if it doesn't exist + if (!config.mcpServers[serverName].autoApprove) { + config.mcpServers[serverName].autoApprove = [] + } + + const autoApprove = config.mcpServers[serverName].autoApprove + const toolIndex = autoApprove.indexOf(toolName) + + if (shouldAllow && toolIndex === -1) { + // Add tool to autoApprove list + autoApprove.push(toolName) + } else if (!shouldAllow && toolIndex !== -1) { + // Remove tool from autoApprove list + autoApprove.splice(toolIndex, 1) + } + + // Write updated config back to file + await fs.writeFile(settingsPath, JSON.stringify(config, null, 2)) + + // Update the tools list to reflect the change + const connection = this.connections.find((conn) => conn.server.name === serverName) + if (connection) { + connection.server.tools = await this.fetchToolsList(serverName) + await this.notifyWebviewOfServerChanges() + } + } catch (error) { + console.error("Failed to update autoApprove settings:", error) + vscode.window.showErrorMessage("Failed to update autoApprove settings") + throw error // Re-throw to ensure the error is properly handled + } + } + async dispose(): Promise { this.removeAllFileWatchers() for (const connection of this.connections) { diff --git a/src/services/ripgrep/index.ts b/src/services/ripgrep/index.ts index b48c60b5b2..b9ebe68c77 100644 --- a/src/services/ripgrep/index.ts +++ b/src/services/ripgrep/index.ts @@ -122,12 +122,7 @@ async function execRipgrep(bin: string, args: string[]): Promise { }) } -export async function regexSearchFiles( - cwd: string, - directoryPath: string, - regex: string, - filePattern?: string, -): Promise { +export async function regexSearchFiles(cwd: string, directoryPath: string, regex: string, filePattern?: string): Promise { const vscodeAppRoot = vscode.env.appRoot const rgPath = await getBinPath(vscodeAppRoot) diff --git a/src/services/tree-sitter/index.ts b/src/services/tree-sitter/index.ts index 83e02ac615..19d0234f01 100644 --- a/src/services/tree-sitter/index.ts +++ b/src/services/tree-sitter/index.ts @@ -50,7 +50,10 @@ export async function parseSourceCodeForDefinitionsTopLevel(dirPath: string): Pr return result ? result : "No source code definitions found." } -function separateFiles(allFiles: string[]): { filesToParse: string[]; remainingFiles: string[] } { +function separateFiles(allFiles: string[]): { + filesToParse: string[] + remainingFiles: string[] +} { const extensions = [ "js", "jsx", diff --git a/src/shared/BrowserSettings.ts b/src/shared/BrowserSettings.ts new file mode 100644 index 0000000000..e4a2f40d75 --- /dev/null +++ b/src/shared/BrowserSettings.ts @@ -0,0 +1,27 @@ +export interface BrowserSettings { + // Viewport size settings + viewport: { + width: number + height: number + } + // Browser mode settings + headless: boolean + // Chrome installation to use + // chromeType: "chromium" | "system" +} + +export const DEFAULT_BROWSER_SETTINGS: BrowserSettings = { + viewport: { + width: 900, + height: 600, + }, + headless: true, + // chromeType: "chromium", +} + +export const BROWSER_VIEWPORT_PRESETS = { + "Large Desktop (1280x800)": { width: 1280, height: 800 }, + "Small Desktop (900x600)": { width: 900, height: 600 }, + "Tablet (768x1024)": { width: 768, height: 1024 }, + "Mobile (360x640)": { width: 360, height: 640 }, +} as const diff --git a/src/shared/ChatSettings.ts b/src/shared/ChatSettings.ts new file mode 100644 index 0000000000..1632082db1 --- /dev/null +++ b/src/shared/ChatSettings.ts @@ -0,0 +1,7 @@ +export interface ChatSettings { + mode: "plan" | "act" +} + +export const DEFAULT_CHAT_SETTINGS: ChatSettings = { + mode: "act", +} diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index b3e58bc4a6..5a93caf07b 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -2,6 +2,8 @@ import { ApiConfiguration, ModelInfo } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" +import { BrowserSettings } from "./BrowserSettings" +import { ChatSettings } from "./ChatSettings" import { HistoryItem } from "./HistoryItem" import { McpServer } from "./mcp" @@ -18,7 +20,12 @@ export interface ExtensionMessage { | "invoke" | "partialMessage" | "openRouterModels" + | "openAiModels" | "mcpServers" + | "relinquishControl" + | "vsCodeLmModels" + | "requestVsCodeLmModels" + | "emailSubscribed" text?: string action?: | "chatButtonClicked" @@ -26,14 +33,18 @@ export interface ExtensionMessage { | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" + | "accountLoginClicked" + | "accountLogoutClicked" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" state?: ExtensionState images?: string[] ollamaModels?: string[] lmStudioModels?: string[] + vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[] filePaths?: string[] partialMessage?: ClineMessage openRouterModels?: Record + openAiModels?: string[] mcpServers?: McpServer[] } @@ -42,10 +53,20 @@ export interface ExtensionState { apiConfiguration?: ApiConfiguration customInstructions?: string uriScheme?: string + currentTaskItem?: HistoryItem + checkpointTrackerErrorMessage?: string clineMessages: ClineMessage[] taskHistory: HistoryItem[] shouldShowAnnouncement: boolean autoApprovalSettings: AutoApprovalSettings + browserSettings: BrowserSettings + chatSettings: ChatSettings + isLoggedIn: boolean + userInfo?: { + displayName: string | null + email: string | null + photoURL: string | null + } } export interface ClineMessage { @@ -54,12 +75,17 @@ export interface ClineMessage { ask?: ClineAsk say?: ClineSay text?: string + reasoning?: string images?: string[] partial?: boolean + lastCheckpointHash?: string + conversationHistoryIndex?: number + conversationHistoryDeletedRange?: [number, number] // for when conversation history is truncated for API requests } export type ClineAsk = | "followup" + | "plan_mode_response" | "command" | "command_output" | "completion_result" @@ -78,6 +104,7 @@ export type ClineSay = | "api_req_started" | "api_req_finished" | "text" + | "reasoning" | "completion_result" | "user_feedback" | "user_feedback_diff" @@ -93,6 +120,7 @@ export type ClineSay = | "mcp_server_response" | "use_mcp_server" | "diff_error" + | "deleted_api_reqs" export interface ClineSayTool { tool: @@ -147,3 +175,5 @@ export interface ClineApiReqInfo { } export type ClineApiReqCancelReason = "streaming_failed" | "user_cancelled" + +export const COMPLETION_RESULT_CHANGES_FLAG = "HAS_CHANGES" diff --git a/src/shared/HistoryItem.ts b/src/shared/HistoryItem.ts index d4539f6441..790c35cef6 100644 --- a/src/shared/HistoryItem.ts +++ b/src/shared/HistoryItem.ts @@ -7,4 +7,8 @@ export type HistoryItem = { cacheWrites?: number cacheReads?: number totalCost: number + + size?: number + shadowGitConfigWorkTree?: string + conversationHistoryDeletedRange?: [number, number] } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 82ad22d95e..a18a3c405a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -1,5 +1,7 @@ import { ApiConfiguration } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" +import { BrowserSettings } from "./BrowserSettings" +import { ChatSettings } from "./ChatSettings" export interface WebviewMessage { type: @@ -23,15 +25,41 @@ export interface WebviewMessage { | "openMention" | "cancelTask" | "refreshOpenRouterModels" + | "refreshOpenAiModels" | "openMcpSettings" | "restartMcpServer" | "autoApprovalSettings" + | "browserSettings" + | "chatSettings" + | "checkpointDiff" + | "checkpointRestore" + | "taskCompletionViewChanges" + | "openExtensionSettings" + | "requestVsCodeLmModels" + | "toggleToolAutoApprove" + | "toggleMcpServer" + | "getLatestState" + | "accountLoginClicked" + | "accountLogoutClicked" + | "subscribeEmail" + // | "relaunchChromeDebugMode" text?: string + disabled?: boolean askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration images?: string[] bool?: boolean + number?: number autoApprovalSettings?: AutoApprovalSettings + browserSettings?: BrowserSettings + chatSettings?: ChatSettings + + // For toggleToolAutoApprove + serverName?: string + toolName?: string + autoApprove?: boolean } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" + +export type ClineCheckpointRestore = "task" | "workspace" | "taskAndWorkspace" diff --git a/src/shared/api.ts b/src/shared/api.ts index 868e9f06e9..a9eacd619f 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -8,10 +8,16 @@ export type ApiProvider = | "lmstudio" | "gemini" | "openai-native" + | "deepseek" + | "mistral" + | "vscode-lm" + | "litellm" export interface ApiHandlerOptions { apiModelId?: string apiKey?: string // anthropic + liteLlmBaseUrl?: string + liteLlmModelId?: string anthropicBaseUrl?: string openRouterApiKey?: string openRouterModelId?: string @@ -32,7 +38,10 @@ export interface ApiHandlerOptions { lmStudioBaseUrl?: string geminiApiKey?: string openAiNativeApiKey?: string + deepSeekApiKey?: string + mistralApiKey?: string azureApiVersion?: string + vsCodeLmModelSelector?: any } export type ApiConfiguration = ApiHandlerOptions & { @@ -55,7 +64,7 @@ export interface ModelInfo { } // Anthropic -// https://docs.anthropic.com/en/docs/about-claude/models +// https://docs.anthropic.com/en/docs/about-claude/models // prices updated 2025-01-02 export type AnthropicModelId = keyof typeof anthropicModels export const anthropicDefaultModelId: AnthropicModelId = "claude-3-5-sonnet-20241022" export const anthropicModels = { @@ -75,10 +84,10 @@ export const anthropicModels = { contextWindow: 200_000, supportsImages: false, supportsPromptCache: true, - inputPrice: 1.0, - outputPrice: 5.0, - cacheWritesPrice: 1.25, - cacheReadsPrice: 0.1, + inputPrice: 0.8, + outputPrice: 4.0, + cacheWritesPrice: 1.0, + cacheReadsPrice: 0.08, }, "claude-3-opus-20240229": { maxTokens: 4096, @@ -237,6 +246,14 @@ export const openAiModelInfoSaneDefaults: ModelInfo = { export type GeminiModelId = keyof typeof geminiModels export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-1219" export const geminiModels = { + "gemini-2.0-flash-thinking-exp-01-21": { + maxTokens: 65536, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, "gemini-2.0-flash-thinking-exp-1219": { maxTokens: 8192, contextWindow: 32_767, @@ -308,7 +325,23 @@ export const geminiModels = { export type OpenAiNativeModelId = keyof typeof openAiNativeModels export const openAiNativeDefaultModelId: OpenAiNativeModelId = "gpt-4o" export const openAiNativeModels = { + "o3-mini": { + maxTokens: 100_000, + contextWindow: 200_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 1.1, + outputPrice: 4.4, + }, // don't support tool use yet + o1: { + maxTokens: 100_000, + contextWindow: 200_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 15, + outputPrice: 60, + }, "o1-preview": { maxTokens: 32_768, contextWindow: 128_000, @@ -322,16 +355,16 @@ export const openAiNativeModels = { contextWindow: 128_000, supportsImages: true, supportsPromptCache: false, - inputPrice: 3, - outputPrice: 12, + inputPrice: 1.1, + outputPrice: 4.4, }, "gpt-4o": { maxTokens: 4_096, contextWindow: 128_000, supportsImages: true, supportsPromptCache: false, - inputPrice: 5, - outputPrice: 15, + inputPrice: 2.5, + outputPrice: 10, }, "gpt-4o-mini": { maxTokens: 16_384, @@ -347,3 +380,122 @@ export const openAiNativeModels = { // https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation // https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#api-specs export const azureOpenAiDefaultApiVersion = "2024-08-01-preview" + +// DeepSeek +// https://api-docs.deepseek.com/quick_start/pricing +export type DeepSeekModelId = keyof typeof deepSeekModels +export const deepSeekDefaultModelId: DeepSeekModelId = "deepseek-chat" +export const deepSeekModels = { + "deepseek-chat": { + maxTokens: 8_000, + contextWindow: 64_000, + supportsImages: false, + supportsPromptCache: true, // supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it + inputPrice: 0, // technically there is no input price, it's all either a cache hit or miss (ApiOptions will not show this) + outputPrice: 0.28, + cacheWritesPrice: 0.14, + cacheReadsPrice: 0.014, + }, + "deepseek-reasoner": { + maxTokens: 8_000, + contextWindow: 64_000, + supportsImages: false, + supportsPromptCache: true, // supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it + inputPrice: 0, // technically there is no input price, it's all either a cache hit or miss (ApiOptions will not show this) + outputPrice: 2.19, + cacheWritesPrice: 0.55, + cacheReadsPrice: 0.14, + }, +} as const satisfies Record + +// Mistral +// https://docs.mistral.ai/getting-started/models/models_overview/ +export type MistralModelId = keyof typeof mistralModels +export const mistralDefaultModelId: MistralModelId = "codestral-2501" +export const mistralModels = { + "mistral-large-2411": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 2.0, + outputPrice: 6.0, + }, + "pixtral-large-2411": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 2.0, + outputPrice: 6.0, + }, + "ministral-3b-2410": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.04, + outputPrice: 0.04, + }, + "ministral-8b-2410": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.1, + }, + "mistral-small-2501": { + maxTokens: 32_000, + contextWindow: 32_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.3, + }, + "pixtral-12b-2409": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.15, + outputPrice: 0.15, + }, + "open-mistral-nemo-2407": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.15, + outputPrice: 0.15, + }, + "open-codestral-mamba": { + maxTokens: 256_000, + contextWindow: 256_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.15, + outputPrice: 0.15, + }, + "codestral-2501": { + maxTokens: 256_000, + contextWindow: 256_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.3, + outputPrice: 0.9, + }, +} as const satisfies Record + +// LiteLLM +// https://docs.litellm.ai/docs/ +export type LiteLLMModelId = string +export const liteLlmDefaultModelId = "gpt-3.5-turbo" +export const liteLlmModelInfoSaneDefaults: ModelInfo = { + maxTokens: 4096, + contextWindow: 8192, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, +} diff --git a/src/shared/combineApiRequests.ts b/src/shared/combineApiRequests.ts index be8721b99d..36f318babf 100644 --- a/src/shared/combineApiRequests.ts +++ b/src/shared/combineApiRequests.ts @@ -29,7 +29,10 @@ export function combineApiRequests(messages: ClineMessage[]): ClineMessage[] { while (j < messages.length) { if (messages[j].type === "say" && messages[j].say === "api_req_finished") { let finishedRequest = JSON.parse(messages[j].text || "{}") - let combinedRequest = { ...startedRequest, ...finishedRequest } + let combinedRequest = { + ...startedRequest, + ...finishedRequest, + } combinedApiRequests.push({ ...messages[i], diff --git a/src/shared/combineCommandSequences.ts b/src/shared/combineCommandSequences.ts index 3e41cd2df9..6d1878149c 100644 --- a/src/shared/combineCommandSequences.ts +++ b/src/shared/combineCommandSequences.ts @@ -25,13 +25,13 @@ export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[ // First pass: combine commands with their outputs for (let i = 0; i < messages.length; i++) { - if (messages[i].type === "ask" && (messages[i].ask === "command" || messages[i].say === "command")) { + if (messages[i].ask === "command" || messages[i].say === "command") { let combinedText = messages[i].text || "" let didAddOutput = false let j = i + 1 while (j < messages.length) { - if (messages[j].type === "ask" && (messages[j].ask === "command" || messages[j].say === "command")) { + if (messages[j].ask === "command" || messages[j].say === "command") { // Stop if we encounter the next command break } @@ -63,7 +63,7 @@ export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[ return messages .filter((msg) => !(msg.ask === "command_output" || msg.say === "command_output")) .map((msg) => { - if (msg.type === "ask" && (msg.ask === "command" || msg.say === "command")) { + if (msg.ask === "command" || msg.say === "command") { const combinedCommand = combinedCommands.find((cmd) => cmd.ts === msg.ts) return combinedCommand || msg } diff --git a/src/shared/getApiMetrics.ts b/src/shared/getApiMetrics.ts index bd7b1bbce0..23fa0516d9 100644 --- a/src/shared/getApiMetrics.ts +++ b/src/shared/getApiMetrics.ts @@ -12,7 +12,7 @@ interface ApiMetrics { * Calculates API metrics from an array of ClineMessages. * * This function processes 'api_req_started' messages that have been combined with their - * corresponding 'api_req_finished' messages by the combineApiRequests function. + * corresponding 'api_req_finished' messages by the combineApiRequests function. It also takes into account 'deleted_api_reqs' messages, which are aggregated from deleted messages. * It extracts and sums up the tokensIn, tokensOut, cacheWrites, cacheReads, and cost from these messages. * * @param messages - An array of ClineMessage objects to process. @@ -35,7 +35,7 @@ export function getApiMetrics(messages: ClineMessage[]): ApiMetrics { } messages.forEach((message) => { - if (message.type === "say" && message.say === "api_req_started" && message.text) { + if (message.type === "say" && (message.say === "api_req_started" || message.say === "deleted_api_reqs") && message.text) { try { const parsedData = JSON.parse(message.text) const { tokensIn, tokensOut, cacheWrites, cacheReads, cost } = parsedData diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index 82efae2f72..a8ae7f70f6 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -1,3 +1,5 @@ +export type McpMode = "full" | "server-use-only" | "off" + export type McpServer = { name: string config: string @@ -6,12 +8,14 @@ export type McpServer = { tools?: McpTool[] resources?: McpResource[] resourceTemplates?: McpResourceTemplate[] + disabled?: boolean } export type McpTool = { name: string description?: string inputSchema?: object + autoApprove?: boolean } export type McpResource = { diff --git a/src/shared/vsCodeSelectorUtils.ts b/src/shared/vsCodeSelectorUtils.ts new file mode 100644 index 0000000000..620fccccd8 --- /dev/null +++ b/src/shared/vsCodeSelectorUtils.ts @@ -0,0 +1,7 @@ +import { LanguageModelChatSelector } from "vscode" + +export const SELECTOR_SEPARATOR = "/" + +export function stringifyVsCodeLmModelSelector(selector: LanguageModelChatSelector): string { + return [selector.vendor, selector.family, selector.version, selector.id].filter(Boolean).join(SELECTOR_SEPARATOR) +} diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 440a353ec6..063cf3bfc7 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -4,7 +4,7 @@ import path from "path" import "should" import * as vscode from "vscode" -const packagePath = path.join(__dirname, "..", "..", "..", "package.json") +const packagePath = path.join(__dirname, "..", "..", "package.json") describe("Cline Extension", () => { after(() => { @@ -23,4 +23,69 @@ describe("Cline Extension", () => { await new Promise((resolve) => setTimeout(resolve, 400)) await vscode.commands.executeCommand("cline.plusButtonClicked") }) + + // New test to verify xvfb and webview functionality + it("should create and display a webview panel", async () => { + // Create a webview panel + const panel = vscode.window.createWebviewPanel("testWebview", "CI/CD Test", vscode.ViewColumn.One, { + enableScripts: true, + }) + + // Set some HTML content + panel.webview.html = ` + + + + + xvfb Test + + +
Testing xvfb display server
+ + + ` + + // Verify panel exists + should.exist(panel) + panel.visible.should.be.true() + + // Clean up + panel.dispose() + }) + + // Test webview message passing + it("should handle webview messages", async () => { + const panel = vscode.window.createWebviewPanel("testWebview", "Message Test", vscode.ViewColumn.One, { + enableScripts: true, + }) + + // Set up message handling + const messagePromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => resolve(message.text), undefined) + }) + + // Add message sending script + panel.webview.html = ` + + + + + Message Test + + + + + + ` + + // Wait for message + const message = await messagePromise + message.should.equal("test-message") + + // Clean up + panel.dispose() + }) }) diff --git a/src/test/shell.test.ts b/src/test/shell.test.ts new file mode 100644 index 0000000000..51d0e85dc9 --- /dev/null +++ b/src/test/shell.test.ts @@ -0,0 +1,235 @@ +import { describe, it, beforeEach, afterEach } from "mocha" +import { expect } from "chai" +import { getShell } from "../utils/shell" +import * as vscode from "vscode" +import { userInfo } from "os" + +describe("Shell Detection Tests", () => { + let originalPlatform: string + let originalEnv: NodeJS.ProcessEnv + let originalGetConfig: any + let originalUserInfo: any + + // Helper to mock VS Code configuration + function mockVsCodeConfig(platformKey: string, defaultProfileName: string | null, profiles: Record) { + vscode.workspace.getConfiguration = () => + ({ + get: (key: string) => { + if (key === `defaultProfile.${platformKey}`) { + return defaultProfileName + } + if (key === `profiles.${platformKey}`) { + return profiles + } + return undefined + }, + }) as any + } + + beforeEach(() => { + // Store original references + originalPlatform = process.platform + originalEnv = { ...process.env } + originalGetConfig = vscode.workspace.getConfiguration + originalUserInfo = userInfo + + // Clear environment variables for a clean test + delete process.env.SHELL + delete process.env.COMSPEC + + // Default userInfo() mock + ;(userInfo as any) = () => ({ shell: null }) + }) + + afterEach(() => { + // Restore everything + Object.defineProperty(process, "platform", { value: originalPlatform }) + process.env = originalEnv + vscode.workspace.getConfiguration = originalGetConfig + ;(userInfo as any) = originalUserInfo + }) + + // -------------------------------------------------------------------------- + // Windows Shell Detection + // -------------------------------------------------------------------------- + describe("Windows Shell Detection", () => { + beforeEach(() => { + Object.defineProperty(process, "platform", { value: "win32" }) + }) + + it("uses explicit PowerShell 7 path from VS Code config (profile path)", () => { + mockVsCodeConfig("windows", "PowerShell", { + PowerShell: { path: "C:\\Program Files\\PowerShell\\7\\pwsh.exe" }, + }) + expect(getShell()).to.equal("C:\\Program Files\\PowerShell\\7\\pwsh.exe") + }) + + it("uses PowerShell 7 path if source is 'PowerShell' but no explicit path", () => { + mockVsCodeConfig("windows", "PowerShell", { + PowerShell: { source: "PowerShell" }, + }) + expect(getShell()).to.equal("C:\\Program Files\\PowerShell\\7\\pwsh.exe") + }) + + it("falls back to legacy PowerShell if profile includes 'powershell' but no path/source", () => { + mockVsCodeConfig("windows", "PowerShell", { + PowerShell: {}, + }) + expect(getShell()).to.equal("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe") + }) + + it("uses WSL bash when profile indicates WSL source", () => { + mockVsCodeConfig("windows", "WSL", { + WSL: { source: "WSL" }, + }) + expect(getShell()).to.equal("/bin/bash") + }) + + it("uses WSL bash when profile name includes 'wsl'", () => { + mockVsCodeConfig("windows", "Ubuntu WSL", { + "Ubuntu WSL": {}, + }) + expect(getShell()).to.equal("/bin/bash") + }) + + it("defaults to cmd.exe if no special profile is matched", () => { + mockVsCodeConfig("windows", "CommandPrompt", { + CommandPrompt: {}, + }) + expect(getShell()).to.equal("C:\\Windows\\System32\\cmd.exe") + }) + + it("respects userInfo() if no VS Code config is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => ({ shell: "C:\\Custom\\PowerShell.exe" }) + + expect(getShell()).to.equal("C:\\Custom\\PowerShell.exe") + }) + + it("respects an odd COMSPEC if no userInfo shell is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + process.env.COMSPEC = "D:\\CustomCmd\\cmd.exe" + + expect(getShell()).to.equal("D:\\CustomCmd\\cmd.exe") + }) + }) + + // -------------------------------------------------------------------------- + // macOS Shell Detection + // -------------------------------------------------------------------------- + describe("macOS Shell Detection", () => { + beforeEach(() => { + Object.defineProperty(process, "platform", { value: "darwin" }) + }) + + it("uses VS Code profile path if available", () => { + mockVsCodeConfig("osx", "MyCustomShell", { + MyCustomShell: { path: "/usr/local/bin/fish" }, + }) + expect(getShell()).to.equal("/usr/local/bin/fish") + }) + + it("falls back to userInfo().shell if no VS Code config is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => ({ shell: "/opt/homebrew/bin/zsh" }) + + expect(getShell()).to.equal("/opt/homebrew/bin/zsh") + }) + + it("falls back to SHELL env var if no userInfo shell is found", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + process.env.SHELL = "/usr/local/bin/zsh" + + expect(getShell()).to.equal("/usr/local/bin/zsh") + }) + + it("falls back to /bin/zsh if no config, userInfo, or env variable is set", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + // userInfo => null, SHELL => undefined + expect(getShell()).to.equal("/bin/zsh") + }) + }) + + // -------------------------------------------------------------------------- + // Linux Shell Detection + // -------------------------------------------------------------------------- + describe("Linux Shell Detection", () => { + beforeEach(() => { + Object.defineProperty(process, "platform", { value: "linux" }) + }) + + it("uses VS Code profile path if available", () => { + mockVsCodeConfig("linux", "CustomProfile", { + CustomProfile: { path: "/usr/bin/fish" }, + }) + expect(getShell()).to.equal("/usr/bin/fish") + }) + + it("falls back to userInfo().shell if no VS Code config is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => ({ shell: "/usr/bin/zsh" }) + + expect(getShell()).to.equal("/usr/bin/zsh") + }) + + it("falls back to SHELL env var if no userInfo shell is found", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + process.env.SHELL = "/usr/bin/fish" + + expect(getShell()).to.equal("/usr/bin/fish") + }) + + it("falls back to /bin/bash if nothing is set", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + // userInfo => null, SHELL => undefined + expect(getShell()).to.equal("/bin/bash") + }) + }) + + // -------------------------------------------------------------------------- + // Unknown Platform & Error Handling + // -------------------------------------------------------------------------- + describe("Unknown Platform / Error Handling", () => { + it("falls back to /bin/sh for unknown platforms", () => { + Object.defineProperty(process, "platform", { value: "sunos" }) + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + + expect(getShell()).to.equal("/bin/sh") + }) + + it("handles VS Code config errors gracefully, falling back to userInfo shell if present", () => { + Object.defineProperty(process, "platform", { value: "linux" }) + vscode.workspace.getConfiguration = () => { + throw new Error("Configuration error") + } + ;(userInfo as any) = () => ({ shell: "/bin/bash" }) + + expect(getShell()).to.equal("/bin/bash") + }) + + it("handles userInfo errors gracefully, falling back to environment variable if present", () => { + Object.defineProperty(process, "platform", { value: "darwin" }) + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => { + throw new Error("userInfo error") + } + process.env.SHELL = "/bin/zsh" + + expect(getShell()).to.equal("/bin/zsh") + }) + + it("falls back fully to default shell paths if everything fails", () => { + Object.defineProperty(process, "platform", { value: "linux" }) + vscode.workspace.getConfiguration = () => { + throw new Error("Configuration error") + } + ;(userInfo as any) = () => { + throw new Error("userInfo error") + } + // No SHELL in env + delete process.env.SHELL + + expect(getShell()).to.equal("/bin/bash") + }) + }) +}) diff --git a/src/test/suite/extension.test.js b/src/test/suite/extension.test.js new file mode 100644 index 0000000000..f9d3305db0 --- /dev/null +++ b/src/test/suite/extension.test.js @@ -0,0 +1,37 @@ +const { expect } = require("chai") +const vscode = require("vscode") + +describe("Extension Tests", function () { + this.timeout(60000) // Increased timeout for extension operations + + it("should activate extension successfully", async () => { + // Get the extension + const extension = vscode.extensions.getExtension("saoudrizwan.claude-dev") + expect(extension).to.not.be.undefined + + // Activate the extension if not already activated + if (!extension.isActive) { + await extension.activate() + } + expect(extension.isActive).to.be.true + }) + + it("should open sidebar view", async () => { + // Execute the command to open sidebar + await vscode.commands.executeCommand("cline.plusButtonClicked") + + // Wait for sidebar to be visible + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Get all views + const views = vscode.window.visibleTextEditors + // Just verify the command executed without error + // The actual view verification is handled in the TypeScript tests + }) + + it("should handle basic commands", async () => { + // Test basic command execution + await vscode.commands.executeCommand("cline.historyButtonClicked") + // Success if no error thrown + }) +}) diff --git a/src/test/suite/index.js b/src/test/suite/index.js new file mode 100644 index 0000000000..36dccbf9f0 --- /dev/null +++ b/src/test/suite/index.js @@ -0,0 +1,43 @@ +const path = require("path") +const Mocha = require("mocha") +const glob = require("glob") + +async function run() { + // Create the mocha test + const mocha = new Mocha({ + ui: "bdd", + color: true, + timeout: 60000, // Increased timeout for extension operations + }) + + const testsRoot = path.resolve(__dirname, ".") + + try { + // Find all test files + const files = await glob("*.test.js", { cwd: testsRoot }) + + // Add files to the test suite + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))) + + // Run the mocha test + return new Promise((resolve, reject) => { + try { + // Run the tests + mocha.run((failures) => { + if (failures > 0) { + reject(new Error(`${failures} tests failed.`)) + } else { + resolve() + } + }) + } catch (err) { + reject(err) + } + }) + } catch (err) { + console.error("Failed to run tests:", err) + throw err + } +} + +module.exports = { run } diff --git a/src/test/webview/chat-native.test.ts b/src/test/webview/chat-native.test.ts new file mode 100644 index 0000000000..775af4b7ae --- /dev/null +++ b/src/test/webview/chat-native.test.ts @@ -0,0 +1,116 @@ +import * as vscode from "vscode" +import { describe, it, beforeEach, afterEach } from "mocha" +import { strict as assert } from "assert" +import { join } from "path" +describe("Chat Integration Tests", () => { + let panel: vscode.WebviewPanel + let disposables: vscode.Disposable[] = [] + + beforeEach(async () => { + // Create VSCode webview panel + panel = vscode.window.createWebviewPanel("testWebview", "Chat Test", vscode.ViewColumn.One, { + enableScripts: true, + retainContextWhenHidden: true, + }) + + // Set up minimal test webview + panel.webview.html = ` + + + + + + + +
+ + + ` + }) + + afterEach(() => { + panel.dispose() + disposables.forEach((d) => d.dispose()) + disposables = [] + }) + + it("should send chat messages", async () => { + // Set up message listener + const messagePromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => { + if (message.type === "newTask") { + resolve(message) + } + }) + }) + + // Trigger send message + await panel.webview.postMessage({ + type: "sendMessage", + text: "Create a hello world app", + }) + + // Verify message was sent + const message = await messagePromise + assert.equal(message.type, "newTask") + assert.equal(message.text, "Create a hello world app") + }) + + it("should toggle between plan and act modes", async () => { + // Set up state change listener + const stateChangePromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => { + if (message.type === "chatSettings") { + resolve(message) + } + }) + }) + + // Trigger mode toggle + await panel.webview.postMessage({ type: "toggleMode" }) + + // Verify mode changed + const stateChange = await stateChangePromise + assert.equal(stateChange.chatSettings.mode, "act") + }) + + it("should handle tool approval flow", async () => { + // Set up approval listener + const approvalPromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => { + if (message.type === "askResponse") { + resolve(message) + } + }) + }) + + // Trigger tool approval + await panel.webview.postMessage({ + type: "invoke", + invoke: "primaryButtonClick", + }) + + // Verify approval was sent + const response = await approvalPromise + assert.equal(response.type, "askResponse") + assert.equal(response.askResponse, "yesButtonClicked") + }) +}) diff --git a/src/utils/shell.ts b/src/utils/shell.ts new file mode 100644 index 0000000000..8871550a0e --- /dev/null +++ b/src/utils/shell.ts @@ -0,0 +1,227 @@ +import * as vscode from "vscode" +import { userInfo } from "os" + +const SHELL_PATHS = { + // Windows paths + POWERSHELL_7: "C:\\Program Files\\PowerShell\\7\\pwsh.exe", + POWERSHELL_LEGACY: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + CMD: "C:\\Windows\\System32\\cmd.exe", + WSL_BASH: "/bin/bash", + // Unix paths + MAC_DEFAULT: "/bin/zsh", + LINUX_DEFAULT: "/bin/bash", + CSH: "/bin/csh", + BASH: "/bin/bash", + KSH: "/bin/ksh", + SH: "/bin/sh", + ZSH: "/bin/zsh", + DASH: "/bin/dash", + TCSH: "/bin/tcsh", + FALLBACK: "/bin/sh", +} as const + +interface MacTerminalProfile { + path?: string +} + +type MacTerminalProfiles = Record + +interface WindowsTerminalProfile { + path?: string + source?: "PowerShell" | "WSL" +} + +type WindowsTerminalProfiles = Record + +interface LinuxTerminalProfile { + path?: string +} + +type LinuxTerminalProfiles = Record + +// ----------------------------------------------------- +// 1) VS Code Terminal Configuration Helpers +// ----------------------------------------------------- + +function getWindowsTerminalConfig() { + try { + const config = vscode.workspace.getConfiguration("terminal.integrated") + const defaultProfileName = config.get("defaultProfile.windows") + const profiles = config.get("profiles.windows") || {} + return { defaultProfileName, profiles } + } catch { + return { defaultProfileName: null, profiles: {} as WindowsTerminalProfiles } + } +} + +function getMacTerminalConfig() { + try { + const config = vscode.workspace.getConfiguration("terminal.integrated") + const defaultProfileName = config.get("defaultProfile.osx") + const profiles = config.get("profiles.osx") || {} + return { defaultProfileName, profiles } + } catch { + return { defaultProfileName: null, profiles: {} as MacTerminalProfiles } + } +} + +function getLinuxTerminalConfig() { + try { + const config = vscode.workspace.getConfiguration("terminal.integrated") + const defaultProfileName = config.get("defaultProfile.linux") + const profiles = config.get("profiles.linux") || {} + return { defaultProfileName, profiles } + } catch { + return { defaultProfileName: null, profiles: {} as LinuxTerminalProfiles } + } +} + +// ----------------------------------------------------- +// 2) Platform-Specific VS Code Shell Retrieval +// ----------------------------------------------------- + +/** Attempts to retrieve a shell path from VS Code config on Windows. */ +function getWindowsShellFromVSCode(): string | null { + const { defaultProfileName, profiles } = getWindowsTerminalConfig() + if (!defaultProfileName) { + return null + } + + const profile = profiles[defaultProfileName] + + // If the profile name indicates PowerShell, do version-based detection. + // In testing it was found these typically do not have a path, and this + // implementation manages to deductively get the corect version of PowerShell + if (defaultProfileName.toLowerCase().includes("powershell")) { + if (profile?.path) { + // If there's an explicit PowerShell path, return that + return profile.path + } else if (profile?.source === "PowerShell") { + // If the profile is sourced from PowerShell, assume the newest + return SHELL_PATHS.POWERSHELL_7 + } + // Otherwise, assume legacy Windows PowerShell + return SHELL_PATHS.POWERSHELL_LEGACY + } + + // If there's a specific path, return that immediately + if (profile.path) { + return profile.path + } + + // If the profile indicates WSL + if (profile?.source === "WSL" || defaultProfileName.toLowerCase().includes("wsl")) { + return SHELL_PATHS.WSL_BASH + } + + // If nothing special detected, we assume cmd + return SHELL_PATHS.CMD +} + +/** Attempts to retrieve a shell path from VS Code config on macOS. */ +function getMacShellFromVSCode(): string | null { + const { defaultProfileName, profiles } = getMacTerminalConfig() + if (!defaultProfileName) { + return null + } + + const profile = profiles[defaultProfileName] + return profile?.path || null +} + +/** Attempts to retrieve a shell path from VS Code config on Linux. */ +function getLinuxShellFromVSCode(): string | null { + const { defaultProfileName, profiles } = getLinuxTerminalConfig() + if (!defaultProfileName) { + return null + } + + const profile = profiles[defaultProfileName] + return profile?.path || null +} + +// ----------------------------------------------------- +// 3) General Fallback Helpers +// ----------------------------------------------------- + +/** + * Tries to get a user’s shell from os.userInfo() (works on Unix if the + * underlying system call is supported). Returns null on error or if not found. + */ +function getShellFromUserInfo(): string | null { + try { + const { shell } = userInfo() + return shell || null + } catch { + return null + } +} + +/** Returns the environment-based shell variable, or null if not set. */ +function getShellFromEnv(): string | null { + const { env } = process + + if (process.platform === "win32") { + // On Windows, COMSPEC typically holds cmd.exe + return env.COMSPEC || "C:\\Windows\\System32\\cmd.exe" + } + + if (process.platform === "darwin") { + // On macOS/Linux, SHELL is commonly the environment variable + return env.SHELL || "/bin/zsh" + } + + if (process.platform === "linux") { + // On Linux, SHELL is commonly the environment variable + return env.SHELL || "/bin/bash" + } + return null +} + +// ----------------------------------------------------- +// 4) Publicly Exposed Shell Getter +// ----------------------------------------------------- + +export function getShell(): string { + // 1. Check VS Code config first. + if (process.platform === "win32") { + // Special logic for Windows + const windowsShell = getWindowsShellFromVSCode() + if (windowsShell) { + return windowsShell + } + } else if (process.platform === "darwin") { + // macOS from VS Code + const macShell = getMacShellFromVSCode() + if (macShell) { + return macShell + } + } else if (process.platform === "linux") { + // Linux from VS Code + const linuxShell = getLinuxShellFromVSCode() + if (linuxShell) { + return linuxShell + } + } + + // 2. If no shell from VS Code, try userInfo() + const userInfoShell = getShellFromUserInfo() + if (userInfoShell) { + return userInfoShell + } + + // 3. If still nothing, try environment variable + const envShell = getShellFromEnv() + if (envShell) { + return envShell + } + + // 4. Finally, fall back to a default + if (process.platform === "win32") { + // On Windows, if we got here, we have no config, no COMSPEC, and one very messed up operating system. + // Use CMD as a last resort + return SHELL_PATHS.CMD + } + // On macOS/Linux, fallback to a POSIX shell - This is the behavior of our old shell detection method. + return SHELL_PATHS.FALLBACK +} diff --git a/src/utils/string.ts b/src/utils/string.ts new file mode 100644 index 0000000000..83e364d55e --- /dev/null +++ b/src/utils/string.ts @@ -0,0 +1,22 @@ +/** + * Fixes incorrectly escaped HTML entities in AI model outputs + * @param text String potentially containing incorrectly escaped HTML entities from AI models + * @returns String with HTML entities converted back to normal characters + */ +export function fixModelHtmlEscaping(text: string): string { + return text + .replace(/>/g, ">") + .replace(/</g, "<") + .replace(/"/g, '"') + .replace(/&/g, "&") + .replace(/'/g, "'") +} + +/** + * Removes invalid characters (like the replacement character �) from a string + * @param text String potentially containing invalid characters + * @returns String with invalid characters removed + */ +export function removeInvalidChars(text: string): string { + return text.replace(/\uFFFD/g, "") +} diff --git a/tsconfig.test.json b/tsconfig.test.json index 40ca1269d2..92f67542f5 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -8,7 +8,11 @@ "compilerOptions": { "module": "commonjs", "moduleResolution": "node", - "types": ["node", "mocha", "should", "vscode"] + "types": ["node", "mocha", "should", "vscode", "chai"], + "typeRoots": ["./node_modules/@types", "./src/test/types"], + "outDir": "out", + "rootDir": "src" }, - "include": ["src/**/*.test.ts"] + "include": ["src/**/*.test.ts"], + "exclude": ["src/test/**/*.js"] } diff --git a/webview-ui/matchMedia.js b/webview-ui/matchMedia.js new file mode 100644 index 0000000000..95ddfdf698 --- /dev/null +++ b/webview-ui/matchMedia.js @@ -0,0 +1,16 @@ +// "Official" jest workaround for mocking window.matchMedia() +// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom + +Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // Deprecated + removeListener: vi.fn(), // Deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}) diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index ee8d460f5e..faec4c48fa 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -8,38 +8,42 @@ "name": "webview-ui", "version": "0.1.0", "dependencies": { - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.18.101", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", "fuse.js": "^7.0.0", + "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-remark": "^2.1.0", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "react-textarea-autosize": "^8.5.3", "react-use": "^17.5.1", "react-virtuoso": "^4.7.13", "rehype-highlight": "^7.0.0", "rewire": "^7.0.0", "styled-components": "^6.1.13", - "typescript": "^4.9.5", + "typescript": "^5.7.3", "web-vitals": "^2.1.4" }, "devDependencies": { - "@types/vscode-webview": "^1.57.5" + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^15.0.6", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^20.x", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@types/vscode-webview": "^1.57.5", + "jsdom": "^25.0.1", + "vitest": "^2.1.8" } }, "node_modules/@adobe/css-tools": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", - "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true, "license": "MIT" }, "node_modules/@alloc/quick-lru": { @@ -67,13 +71,35 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "node_modules/@asamuzakjp/css-color": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.3.tgz", + "integrity": "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@csstools/css-calc": "^2.1.1", + "@csstools/css-color-parser": "^3.0.7", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -81,30 +107,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", + "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -129,9 +155,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.7.tgz", - "integrity": "sha512-SO5E3bVxDuxyNxM5agFv480YA2HO6ohZbGxbazZdIk3KQOPOGVNw6q78I9/lbviIf95eq6tPozeYnJLbjnC8IA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.5.tgz", + "integrity": "sha512-Kkm8C8uxI842AwQADxl0GbcG1rupELYLShazYEZO/2DYjhyWXJIOUVOE3tBYm6JXzUCNJOZEzqc4rCW/jsEQYQ==", "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -165,54 +191,42 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -230,19 +244,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@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.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -262,13 +274,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -288,9 +300,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -303,80 +315,41 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -386,35 +359,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -424,14 +397,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -440,119 +413,81 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", + "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.5" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -561,13 +496,28 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -577,12 +527,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -592,14 +542,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -609,13 +559,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -642,14 +592,14 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", - "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-decorators": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -791,12 +741,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", - "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -805,37 +755,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", - "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", + "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -845,12 +771,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -860,12 +786,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -899,12 +825,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1016,12 +942,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1047,12 +973,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1062,15 +988,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1080,14 +1005,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1097,12 +1022,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1112,12 +1037,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1127,13 +1052,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1143,14 +1068,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1160,18 +1084,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@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" }, "engines": { @@ -1181,14 +1103,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1198,12 +1129,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1213,13 +1144,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1229,12 +1160,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1243,14 +1174,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1260,13 +1206,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1276,13 +1221,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1292,13 +1236,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", - "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.26.5.tgz", + "integrity": "sha512-eGK26RsbIkYUns3Y8qKl362juDDYK+wEdPGHGrhzUl6CewZFo55VZ7hg+CyMFU4dd5QQakBN86nBMpRsFpRvbQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-flow": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/plugin-syntax-flow": "^7.26.0" }, "engines": { "node": ">=6.9.0" @@ -1308,13 +1252,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1324,14 +1268,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1341,13 +1285,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1357,12 +1300,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1372,13 +1315,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1388,12 +1330,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1403,13 +1345,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1419,14 +1361,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1436,15 +1377,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@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" }, "engines": { "node": ">=6.9.0" @@ -1454,13 +1395,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1470,13 +1411,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1486,12 +1427,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1501,13 +1442,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1517,13 +1457,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1533,15 +1472,14 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1551,13 +1489,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1567,13 +1505,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1583,14 +1520,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1600,12 +1536,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1615,13 +1551,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1631,15 +1567,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1649,12 +1584,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1664,12 +1599,12 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", - "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1679,12 +1614,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", - "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1694,16 +1629,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1713,12 +1648,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", - "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.24.7" + "@babel/plugin-transform-react-jsx": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1728,13 +1663,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", - "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1744,12 +1679,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1759,13 +1694,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1775,15 +1726,15 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", - "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, @@ -1804,12 +1755,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1819,13 +1770,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1835,12 +1786,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1850,12 +1801,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1865,12 +1816,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1880,15 +1831,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", - "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz", + "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1898,12 +1850,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1913,13 +1865,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1929,13 +1881,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1945,13 +1897,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1961,91 +1913,79 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@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-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.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@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.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@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.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.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.25.9", + "@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.25.9", + "@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.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@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.10.4", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -2079,17 +2019,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", - "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz", + "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.24.7", - "@babel/plugin-transform-react-jsx-development": "^7.24.7", - "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2099,16 +2039,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2117,16 +2057,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "license": "MIT" - }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2136,33 +2070,30 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz", + "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.5", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.5", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2170,15 +2101,23 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", + "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2190,6 +2129,121 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "license": "MIT" }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", + "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz", + "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz", + "integrity": "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.0.1", + "@csstools/css-calc": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", @@ -2497,25 +2551,419 @@ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -2544,68 +2992,23 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -2650,6 +3053,18 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", @@ -2679,6 +3094,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -2712,6 +3142,15 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2721,6 +3160,80 @@ "node": ">=6" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -2747,76 +3260,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/core": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", @@ -2864,88 +3307,6 @@ } } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -3036,85 +3397,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/schemas": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", @@ -3141,15 +3423,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@jest/test-result": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", @@ -3206,91 +3479,12 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/@jest/transform/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT" }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/types": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", @@ -3307,80 +3501,10 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -3420,9 +3544,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -3478,18 +3602,18 @@ } }, "node_modules/@microsoft/fast-element": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.13.0.tgz", - "integrity": "sha512-iFhzKbbD0cFRo9cEzLS3Tdo9BYuatdxmCEKCpZs1Cro/93zNMpZ/Y9/Z7SknmW6fhDZbpBvtO8lLh9TFEcNVAQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.14.0.tgz", + "integrity": "sha512-zXvuSOzvsu8zDTy9eby8ix8VqLop2rwKRgp++ZN2kTCsoB3+QJVoaGD2T/Cyso2ViZQFXNpiNCVKfnmxBvmWkQ==", "license": "MIT" }, "node_modules/@microsoft/fast-foundation": { - "version": "2.49.6", - "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.49.6.tgz", - "integrity": "sha512-DZVr+J/NIoskFC1Y6xnAowrMkdbf2d5o7UyWK6gW5AiQ6S386Ql8dw4KcC4kHaeE1yL2CKvweE79cj6ZhJhTvA==", + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.50.0.tgz", + "integrity": "sha512-8mFYG88Xea1jZf2TI9Lm/jzZ6RWR8x29r24mGuLojNYqIR2Bl8+hnswoV6laApKdCbGMPKnsAL/O68Q0sRxeVg==", "license": "MIT", "dependencies": { - "@microsoft/fast-element": "^1.13.0", + "@microsoft/fast-element": "^1.14.0", "@microsoft/fast-web-utilities": "^5.4.1", "tabbable": "^5.2.0", "tslib": "^1.13.0" @@ -3502,13 +3626,13 @@ "license": "0BSD" }, "node_modules/@microsoft/fast-react-wrapper": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.3.24.tgz", - "integrity": "sha512-sRnSBIKaO42p4mYoYR60spWVkg89wFxFAgQETIMazAm2TxtlsnsGszJnTwVhXq2Uz+XNiD8eKBkfzK5c/i6/Kw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.3.25.tgz", + "integrity": "sha512-jKzmk2xJV93RL/jEFXEZgBvXlKIY4N4kXy3qrjmBfFpqNi3VjY+oUTWyMnHRMC5EUhIFxD+Y1VD4u9uIPX3jQw==", "license": "MIT", "dependencies": { - "@microsoft/fast-element": "^1.13.0", - "@microsoft/fast-foundation": "^2.49.6" + "@microsoft/fast-element": "^1.14.0", + "@microsoft/fast-foundation": "^2.50.0" }, "peerDependencies": { "react": ">=16.9.0" @@ -3647,6 +3771,15 @@ } } }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3726,10 +3859,282 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "license": "MIT" }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.1.tgz", + "integrity": "sha512-/pqA4DmqyCm8u5YIDzIdlLcEmuvxb0v8fZdFhVMszSpDTgbQKdw3/mB3eMUHIbubtJ6F9j+LtmyCnHTEqIHyzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.1.tgz", + "integrity": "sha512-If3PDskT77q7zgqVqYuj7WG3WC08G1kwXGVFi9Jr8nY6eHucREHkfpX79c0ACAjLj3QIWKPJR7w4i+f5EdLH5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.1.tgz", + "integrity": "sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.1.tgz", + "integrity": "sha512-sFvF+t2+TyUo/ZQqUcifrJIgznx58oFZbdHS9TvHq3xhPVL9nOp+yZ6LKrO9GWTP+6DbFtoyLDbjTpR62Mbr3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.1.tgz", + "integrity": "sha512-NbOa+7InvMWRcY9RG+B6kKIMD/FsnQPH0MWUvDlQB1iXnF/UcKSudCXZtv4lW+C276g3w5AxPbfry5rSYvyeYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.1.tgz", + "integrity": "sha512-JRBRmwvHPXR881j2xjry8HZ86wIPK2CcDw0EXchE1UgU0ubWp9nvlT7cZYKc6bkypBt745b4bglf3+xJ7hXWWw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.1.tgz", + "integrity": "sha512-PKvszb+9o/vVdUzCCjL0sKHukEQV39tD3fepXxYrHE3sTKrRdCydI7uldRLbjLmDA3TFDmh418XH19NOsDRH8g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.1.tgz", + "integrity": "sha512-9WHEMV6Y89eL606ReYowXuGF1Yb2vwfKWKdD1A5h+OYnPZSJvxbEjxTRKPgi7tkP2DSnW0YLab1ooy+i/FQp/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.1.tgz", + "integrity": "sha512-tZWc9iEt5fGJ1CL2LRPw8OttkCBDs+D8D3oEM8mH8S1ICZCtFJhD7DZ3XMGM8kpqHvhGUTvNUYVDnmkj4BDXnw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.1.tgz", + "integrity": "sha512-FTYc2YoTWUsBz5GTTgGkRYYJ5NGJIi/rCY4oK/I8aKowx1ToXeoVVbIE4LGAjsauvlhjfl0MYacxClLld1VrOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.1.tgz", + "integrity": "sha512-F51qLdOtpS6P1zJVRzYM0v6MrBNypyPEN1GfMiz0gPu9jN8ScGaEFIZQwteSsGKg799oR5EaP7+B2jHgL+d+Kw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.1.tgz", + "integrity": "sha512-wO0WkfSppfX4YFm5KhdCCpnpGbtgQNj/tgvYzrVYFKDpven8w2N6Gg5nB6w+wAMO3AIfSTWeTjfVe+uZ23zAlg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.1.tgz", + "integrity": "sha512-iWswS9cIXfJO1MFYtI/4jjlrGb/V58oMu4dYJIKnR5UIwbkzR0PJ09O0PDZT0oJ3LYWXBSWahNf/Mjo6i1E5/g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.1.tgz", + "integrity": "sha512-RKt8NI9tebzmEthMnfVgG3i/XeECkMPS+ibVZjZ6mNekpbbUmkNWuIN2yHsb/mBPyZke4nlI4YqIdFPgKuoyQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.1.tgz", + "integrity": "sha512-WQFLZ9c42ECqEjwg/GHHsouij3pzLXkFdz0UxHa/0OM12LzvX7DzedlY0SIEly2v18YZLRhCRoHZDxbBSWoGYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.1.tgz", + "integrity": "sha512-BLoiyHDOWoS3uccNSADMza6V6vCNiphi94tQlVIL5de+r6r/CCQuNnerf+1g2mnk2b6edp5dk0nhdZ7aEjOBsA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.1.tgz", + "integrity": "sha512-w2l3UnlgYTNNU+Z6wOR8YdaioqfEnwPjIsJ66KxKAf0p+AuL2FHeTX6qvM+p/Ue3XPBVNyVSfCrfZiQh7vZHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.1.tgz", + "integrity": "sha512-Am9H+TGLomPGkBnaPWie4F3x+yQ2rr4Bk2jpwy+iV+Gel9jLAu/KqT8k3X4jxFPW6Zf8OMnehyutsd+eHoq1WQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.1.tgz", + "integrity": "sha512-ar80GhdZb4DgmW3myIS9nRFYcpJRSME8iqWgzH2i44u+IdrzmiXVxeFnExQ5v4JYUSpg94bWjevMG8JHf1Da5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "license": "MIT" + }, "node_modules/@rushstack/eslint-patch": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", - "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.5.tgz", + "integrity": "sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==", "license": "MIT" }, "node_modules/@sinclair/typebox": { @@ -3990,11 +4395,11 @@ } }, "node_modules/@testing-library/dom": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.3.1.tgz", - "integrity": "sha512-q/WL+vlXMpC0uXDyfsMtc1rmotzLV8Y0gq6q1gfrrDjQeHoeLrqHbxdPvPNAh1i+xuJl7+BezywcXArz7vLqKQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -4009,96 +4414,11 @@ "node": ">=18" } }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT", - "peer": true - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.17.0", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.0.1", @@ -4117,25 +4437,11 @@ "yarn": ">=1" } }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/@testing-library/jest-dom/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4145,156 +4451,36 @@ "node": ">=8" } }, - "node_modules/@testing-library/jest-dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@testing-library/jest-dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", + "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", + "@testing-library/dom": "^10.0.0", "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "peerDependencies": { + "@types/react": "^18.0.0", "react": "^18.0.0", "react-dom": "^18.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/react/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@testing-library/react/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@testing-library/user-event": { "version": "13.5.0", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5" @@ -4329,6 +4515,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, "license": "MIT" }, "node_modules/@types/babel__core": { @@ -4411,19 +4598,29 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, "node_modules/@types/express": { @@ -4439,9 +4636,21 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.5.tgz", + "integrity": "sha512-GLZPrd9ckqEBFMcVM/qRFAP0Hg3qiVEojgEFsx/N/zKXsBzbGF6z5FBDpZ0+Xhp1xr+qRZYjfGr1cWHB9oFHSA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -4481,9 +4690,9 @@ "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -4517,6 +4726,7 @@ "version": "27.5.2", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dev": true, "license": "MIT", "dependencies": { "jest-matcher-utils": "^27.0.0", @@ -4526,7 +4736,8 @@ "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", - "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" + "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -4540,6 +4751,21 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/mdast/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -4547,10 +4773,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "16.18.101", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz", - "integrity": "sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==", - "license": "MIT" + "version": "20.17.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", + "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/node-forge": { "version": "1.3.11", @@ -4574,9 +4803,10 @@ "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "dev": true, "license": "MIT" }, "node_modules/@types/q": { @@ -4586,9 +4816,9 @@ "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", "license": "MIT" }, "node_modules/@types/range-parser": { @@ -4598,9 +4828,10 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -4608,12 +4839,13 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "dev": true, "license": "MIT", - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/resolve": { @@ -4692,6 +4924,7 @@ "version": "5.14.9", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dev": true, "license": "MIT", "dependencies": { "@types/jest": "*" @@ -4704,9 +4937,9 @@ "license": "MIT" }, "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, "node_modules/@types/vscode-webview": { @@ -4717,9 +4950,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -4970,15 +5203,159 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "license": "ISC" }, + "node_modules/@vitest/expect": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", + "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", + "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/mocker/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", + "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.8", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", + "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", + "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", + "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@vscode/webview-ui-toolkit": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.4.0.tgz", "integrity": "sha512-modXVHQkZLsxgmd5yoP3ptRC/G8NBDD+ob+ngPiWNQdlrH6H1xR/qgOBD85bfU3BhOB5sZzFWBwwhp9/SfoHww==", + "deprecated": "This package has been deprecated, https://github.com/microsoft/vscode-webview-ui-toolkit/issues/561", "license": "MIT", "dependencies": { "@microsoft/fast-element": "^1.12.0", @@ -4991,155 +5368,156 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", "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" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", "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" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", "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" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", "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" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "node_modules/@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", - "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "license": "MIT" }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", @@ -5173,10 +5551,19 @@ "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5207,15 +5594,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -5257,15 +5635,13 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, "license": "MIT", - "dependencies": { - "debug": "4" - }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -5302,15 +5678,15 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -5347,6 +5723,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", @@ -5381,15 +5769,18 @@ } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/any-promise": { @@ -5418,31 +5809,29 @@ "license": "MIT" }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "deep-equal": "^2.0.5" + "dequal": "^2.0.3" } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -5527,15 +5916,15 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5545,15 +5934,15 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5583,18 +5972,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -5612,19 +5989,18 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -5639,6 +6015,16 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -5646,9 +6032,9 @@ "license": "MIT" }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/asynckit": { @@ -5667,9 +6053,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -5686,11 +6072,11 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -5719,21 +6105,21 @@ } }, "node_modules/axe-core": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", - "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "license": "MPL-2.0", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "engines": { + "node": ">= 0.4" } }, "node_modules/babel-jest": { @@ -5758,84 +6144,14 @@ "@babel/core": "^7.8.0" } }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz", + "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==", "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", + "loader-utils": "^2.0.4", "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, @@ -5921,13 +6237,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -5944,25 +6260,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5975,23 +6291,26 @@ "license": "MIT" }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.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.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-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -6037,6 +6356,16 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -6116,15 +6445,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6153,9 +6473,9 @@ "license": "MIT" }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -6197,9 +6517,9 @@ "license": "BSD-2-Clause" }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "funding": [ { "type": "opencollective", @@ -6216,10 +6536,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -6256,25 +6576,63 @@ } }, "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -6345,9 +6703,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "version": "1.0.30001692", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", + "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", "funding": [ { "type": "opencollective", @@ -6373,18 +6731,37 @@ "node": ">=4" } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/char-regex": { @@ -6426,6 +6803,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/check-types": { "version": "11.2.3", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", @@ -6493,9 +6880,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", "license": "MIT" }, "node_modules/clean-css": { @@ -6510,15 +6897,6 @@ "node": ">= 10.0" } }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -6530,18 +6908,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -6566,13 +6932,33 @@ "node": ">= 4.0" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "license": "MIT" + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/color-convert": { + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", @@ -6581,12 +6967,66 @@ "color-name": "1.1.3" } }, - "node_modules/color-name": { + "node_modules/coa/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -6658,17 +7098,17 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { @@ -6690,12 +7130,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6745,9 +7179,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6763,14 +7197,15 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", "dependencies": { "toggle-selection": "^1.0.6" } }, "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -6779,12 +7214,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", "license": "MIT", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.24.3" }, "funding": { "type": "opencollective", @@ -6792,9 +7227,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz", + "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -6825,9 +7260,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6908,6 +7343,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", "dependencies": { "hyphenate-style-name": "^1.0.3" } @@ -6985,15 +7421,6 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/css-prefers-color-scheme": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", @@ -7043,27 +7470,18 @@ } }, "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "license": "MIT", "dependencies": { - "mdn-data": "2.0.4", + "mdn-data": "2.0.14", "source-map": "^0.6.1" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -7080,6 +7498,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, "license": "MIT" }, "node_modules/cssdb": { @@ -7198,34 +7617,6 @@ "node": ">=8.0.0" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0" - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -7233,21 +7624,24 @@ "license": "MIT" }, "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.2.1.tgz", + "integrity": "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==", + "dev": true, "license": "MIT", "dependencies": { - "cssom": "~0.3.6" + "@asamuzakjp/css-color": "^2.8.2", + "rrweb-cssom": "^0.8.0" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, "license": "MIT" }, "node_modules/csstype": { @@ -7263,28 +7657,28 @@ "license": "BSD-2-Clause" }, "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, "license": "MIT", "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7294,29 +7688,29 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -7328,9 +7722,9 @@ } }, "node_modules/debounce": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.1.1.tgz", - "integrity": "sha512-+xRWxgel9LgTC4PwKlm7TJUK6B6qsEK77NaiNvXmeQ7Y3e6OVVsBC4a9BSptS/mAYceyAz37Oa8JTTuPRft7uQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.2.0.tgz", + "integrity": "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==", "license": "MIT", "engines": { "node": ">=18" @@ -7340,12 +7734,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7368,36 +7762,14 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "license": "MIT" }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, "node_modules/deep-is": { @@ -7558,6 +7930,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, @@ -7627,6 +8000,7 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, "license": "MIT" }, "node_modules/dom-converter": { @@ -7740,6 +8114,20 @@ "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "license": "BSD-2-Clause" }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -7774,9 +8162,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.818", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", - "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", + "version": "1.5.83", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz", + "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==", "license": "ISC" }, "node_modules/emittery": { @@ -7816,9 +8204,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -7856,57 +8244,62 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -7922,13 +8315,10 @@ "license": "MIT" }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -7942,61 +8332,43 @@ "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", + "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.4", - "globalthis": "^1.0.3", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.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" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -8006,14 +8378,15 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -8029,14 +8402,14 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -8045,10 +8418,49 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -8061,12 +8473,15 @@ "license": "MIT" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escodegen": { @@ -8090,27 +8505,18 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -8204,9 +8610,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "license": "MIT", "dependencies": { "debug": "^3.2.7" @@ -8248,34 +8654,36 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -8333,65 +8741,73 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "license": "MIT", "dependencies": { - "aria-query": "~5.1.3", + "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/eslint-plugin-react": { - "version": "7.34.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", - "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", + "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -8512,15 +8928,6 @@ "webpack": "^5.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", @@ -8550,206 +8957,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -8781,9 +8988,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -8904,10 +9111,20 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -8915,7 +9132,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -8929,7 +9146,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -8944,6 +9161,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/debug": { @@ -8964,7 +9185,8 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -8973,16 +9195,16 @@ "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -9017,15 +9239,32 @@ "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" }, + "node_modules/fast-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", + "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastest-stable-stringify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", - "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==" + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", + "license": "MIT" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -9204,16 +9443,19 @@ } }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { @@ -9231,15 +9473,15 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -9266,9 +9508,9 @@ } }, "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -9332,55 +9574,6 @@ } } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -9412,15 +9605,6 @@ "node": ">=10" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", @@ -9439,18 +9623,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -9461,9 +9633,10 @@ } }, "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -9555,15 +9728,17 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -9609,16 +9784,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9642,6 +9822,19 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -9655,14 +9848,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -9749,12 +9942,18 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { @@ -9794,12 +9993,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9845,21 +10044,24 @@ "license": "(Apache-2.0 OR MPL-1.1)" }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { @@ -9875,10 +10077,13 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -9887,9 +10092,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -9944,31 +10149,12 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-to-hyperscript/node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "node_modules/hast-to-hyperscript/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, - "node_modules/hast-to-hyperscript/node_modules/style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/hast-to-hyperscript/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-is-element": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", @@ -9998,12 +10184,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-text/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -10013,6 +10193,15 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -10071,15 +10260,16 @@ } }, "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^1.0.5" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/html-entities": { @@ -10126,9 +10316,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", + "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -10199,9 +10389,9 @@ } }, "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", "license": "MIT" }, "node_modules/http-proxy": { @@ -10219,23 +10409,23 @@ } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, "license": "MIT", "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", @@ -10256,17 +10446,30 @@ } } }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -10281,7 +10484,8 @@ "node_modules/hyphenate-style-name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", - "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==" + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" }, "node_modules/iconv-lite": { "version": "0.6.3", @@ -10326,9 +10530,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -10360,19 +10564,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -10401,6 +10596,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10429,23 +10625,30 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "license": "MIT" + }, "node_modules/inline-style-prefixer": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", "dependencies": { "css-in-js-utils": "^3.1.0" } }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10484,30 +10687,15 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -10523,12 +10711,15 @@ "license": "MIT" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10538,12 +10729,15 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10562,13 +10756,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10613,9 +10807,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -10628,11 +10822,13 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -10643,12 +10839,13 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10692,12 +10889,15 @@ } }, "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10722,12 +10922,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10776,18 +10979,6 @@ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "license": "MIT" }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -10798,12 +10989,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10831,15 +11023,12 @@ } }, "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/is-potential-custom-element-name": { @@ -10849,13 +11038,15 @@ "license": "MIT" }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -10895,12 +11086,12 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -10922,12 +11113,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10937,12 +11129,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10952,12 +11146,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -10985,25 +11179,28 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -11084,15 +11281,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -11108,18 +11296,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", @@ -11134,15 +11310,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", @@ -11157,29 +11324,30 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", - "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -11188,9 +11356,9 @@ } }, "node_modules/jake": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", - "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", @@ -11205,76 +11373,6 @@ "node": ">=10" } }, - "node_modules/jake/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jake/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jake/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -11344,76 +11442,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-cli": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", @@ -11448,76 +11476,6 @@ } } }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-config": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", @@ -11561,76 +11519,6 @@ } } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", @@ -11646,76 +11534,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-docblock": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", @@ -11744,76 +11562,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-environment-jsdom": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", @@ -11832,6 +11580,292 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-environment-jsdom/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/form-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", + "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "license": "Apache-2.0" + }, "node_modules/jest-environment-node": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", @@ -11912,76 +11946,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-leak-detector": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", @@ -12010,76 +11974,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-message-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", @@ -12100,76 +11994,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-mock": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", @@ -12244,76 +12068,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runner": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", @@ -12346,76 +12100,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runtime": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", @@ -12449,76 +12133,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-serializer": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", @@ -12565,76 +12179,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", @@ -12652,76 +12196,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-validate": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", @@ -12739,76 +12213,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watch-typeahead": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", @@ -12889,63 +12293,26 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/jest-watch-typeahead/node_modules/emittery": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", @@ -12958,15 +12325,6 @@ "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", @@ -13081,18 +12439,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-watch-typeahead/node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -13128,24 +12474,39 @@ } }, "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", - "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz", + "integrity": "sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==", "license": "MIT", "engines": { "node": ">=12.20" } }, - "node_modules/jest-watch-typeahead/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/jest-watcher": { @@ -13166,76 +12527,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -13250,15 +12541,6 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -13275,9 +12557,9 @@ } }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -13286,7 +12568,8 @@ "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -13295,57 +12578,51 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "dev": true, "license": "MIT", "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { - "canvas": "^2.5.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -13354,15 +12631,15 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -13521,9 +12798,9 @@ } }, "node_modules/launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "license": "MIT", "dependencies": { "picocolors": "^1.0.0", @@ -13591,15 +12868,18 @@ } }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -13650,6 +12930,13 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "dev": true, + "license": "MIT" + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -13659,6 +12946,21 @@ "tslib": "^2.0.3" } }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -13672,6 +12974,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, "license": "MIT", "bin": { "lz-string": "bin/bin.js" @@ -13719,6 +13022,15 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdast-util-definitions": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", @@ -13732,15 +13044,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-definitions/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/mdast-util-definitions/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" }, "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { "version": "2.0.3", @@ -13771,10 +13079,92 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", + "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "license": "CC0-1.0" }, "node_modules/mdurl": { @@ -13837,6 +13227,26 @@ "node": ">= 0.6" } }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -13896,15 +13306,16 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -13970,9 +13381,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multicast-dns": { @@ -14003,6 +13414,7 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.2.tgz", "integrity": "sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==", + "license": "Unlicense", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "css-tree": "^1.1.2", @@ -14018,35 +13430,10 @@ "react-dom": "*" } }, - "node_modules/nano-css/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/nano-css/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/nano-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -14074,9 +13461,9 @@ "license": "MIT" }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -14114,9 +13501,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, "node_modules/normalize-path": { @@ -14174,9 +13561,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", "license": "MIT" }, "node_modules/object-assign": { @@ -14198,9 +13585,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -14209,22 +13596,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -14235,14 +13606,16 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -14319,30 +13692,14 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -14438,31 +13795,51 @@ "node": ">= 0.8.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-retry": { @@ -14488,9 +13865,9 @@ } }, "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/param-case": { @@ -14552,10 +13929,30 @@ } }, "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "license": "MIT" + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, "node_modules/parseurl": { "version": "1.3.3", @@ -14626,18 +14023,15 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.1.tgz", - "integrity": "sha512-9/8QXrtbGeMB6LxwQd4x1tIMnsmUxMvIH/qWGsccz6bt9Uln3S+sgAaqfQNhbGA8ufzs2fHuP/yqapGgP9Hh2g==", - "license": "ISC", - "engines": { - "node": ">=18" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/path-type": { @@ -14649,6 +14043,23 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -14656,9 +14067,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { @@ -14703,6 +14114,58 @@ "node": ">=8" } }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -14740,6 +14203,21 @@ "node": ">=6" } }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -14771,9 +14249,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "funding": [ { "type": "opencollective", @@ -14791,7 +14269,7 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", + "picocolors": "^1.0.0", "source-map-js": "^1.2.0" }, "engines": { @@ -15292,9 +14770,9 @@ } }, "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "license": "MIT", "engines": { "node": ">=14" @@ -15304,9 +14782,9 @@ } }, "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -15472,13 +14950,13 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -15488,13 +14966,26 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -15503,6 +14994,19 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", @@ -15519,20 +15023,26 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } @@ -15940,9 +15450,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -15977,34 +15487,6 @@ "node": ">= 10" } }, - "node_modules/postcss-svgo/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-svgo/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0" - }, - "node_modules/postcss-svgo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/postcss-svgo/node_modules/svgo": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", @@ -16057,12 +15539,12 @@ } }, "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -16185,10 +15667,16 @@ } }, "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "license": "MIT" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "node_modules/punycode": { "version": "2.3.1", @@ -16293,15 +15781,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/raw-body/node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -16384,92 +15863,6 @@ "node": ">=14" } }, - "node_modules/react-dev-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/react-dev-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/react-dev-utils/node_modules/loader-utils": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", @@ -16479,75 +15872,6 @@ "node": ">= 12.13.0" } }, - "node_modules/react-dev-utils/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -16604,247 +15928,6 @@ "react": ">=16.8" } }, - "node_modules/react-remark/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/react-remark/node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/react-remark/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-remark/node_modules/mdast-util-from-markdown": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/mdast-util-to-hast": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", - "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" - } - }, - "node_modules/react-remark/node_modules/remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^0.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/remark-rehype": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz", - "integrity": "sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==", - "license": "MIT", - "dependencies": { - "mdast-util-to-hast": "^10.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/react-remark/node_modules/unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "license": "MIT", - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -16919,9 +16002,9 @@ } }, "node_modules/react-textarea-autosize": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", - "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==", + "version": "8.5.7", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.7.tgz", + "integrity": "sha512-2MqJ3p0Jh69yt9ktFIaZmORHXw4c4bxSIhCeWiFwmJ9EYKgLmuNII3e9c9b2UO+ijl4StnpZdqpxNIhTdHvqtQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.13", @@ -16932,7 +16015,7 @@ "node": ">=10" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-universal-interface": { @@ -16945,9 +16028,10 @@ } }, "node_modules/react-use": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.5.1.tgz", - "integrity": "sha512-LG/uPEVRflLWMwi3j/sZqR00nF6JGqTTDblkXK2nzXsIvij06hXl1V/MZIlwj1OKIQUtlh1l9jK8gLsRyCQxMg==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.6.0.tgz", + "integrity": "sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==", + "license": "Unlicense", "dependencies": { "@types/js-cookie": "^2.2.6", "@xobotyi/scrollbar-width": "^1.9.5", @@ -16970,9 +16054,10 @@ } }, "node_modules/react-virtuoso": { - "version": "4.7.13", - "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.13.tgz", - "integrity": "sha512-rabPhipwJ8rdA6TDk1vdVqVoU6eOkWukqoC1pNQVBCsvjBvIeJMi9nO079s0L7EsRzAxFFQNahX+8vuuY4F1Qg==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.12.3.tgz", + "integrity": "sha512-6X1p/sU7hecmjDZMAwN+r3go9EVjofKhwkUbVlL8lXhBZecPv9XVCkZ/kBPYOr0Mv0Vl5+Ziwgexg9Kh7+NNXQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -17032,6 +16117,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, "license": "MIT", "dependencies": { "indent-string": "^4.0.0", @@ -17042,18 +16128,19 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -17069,9 +16156,9 @@ "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "license": "MIT", "dependencies": { "regenerate": "^1.4.2" @@ -17102,15 +16189,17 @@ "license": "MIT" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -17120,15 +16209,15 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "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" }, @@ -17136,30 +16225,40 @@ "node": ">=4" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/rehype-highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.0.tgz", - "integrity": "sha512-QtobgRgYoQaK6p1eSr2SD1i61f7bjF2kZHAQHxeCHAuJf7ZUDMvQ7owDq9YTkmar5m5TSUol+2D3bp3KfJf/oA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.1.tgz", + "integrity": "sha512-dB/vVGFsbm7xPglqnYbg0ABg6rAuIWKycTvuXaOO27SgLoOFNoTlniTBtAxp3n5ZyMioW1a3KwiNqgjkb6Skjg==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -17173,30 +16272,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-highlight/node_modules/highlight.js": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", - "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/rehype-highlight/node_modules/lowlight": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.1.0.tgz", - "integrity": "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.0.0", - "highlight.js": "~11.9.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/rehype-react": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-6.2.1.tgz", @@ -17220,6 +16295,32 @@ "node": ">= 0.10" } }, + "node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz", + "integrity": "sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==", + "license": "MIT", + "dependencies": { + "mdast-util-to-hast": "^10.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/renderkid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", @@ -17233,18 +16334,6 @@ "strip-ansi": "^6.0.1" } }, - "node_modules/renderkid/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -17272,21 +16361,25 @@ "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -17303,7 +16396,7 @@ "node": ">=8" } }, - "node_modules/resolve-from": { + "node_modules/resolve-cwd/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -17312,6 +16405,15 @@ "node": ">=8" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/resolve-url-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", @@ -17369,15 +16471,6 @@ "url": "https://opencollective.com/postcss/" } }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve.exports": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", @@ -17432,9 +16525,9 @@ } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "license": "MIT", "bin": { "rollup": "dist/bin/rollup" @@ -17462,15 +16555,6 @@ "rollup": "^2.0.0" } }, - "node_modules/rollup-plugin-terser/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/rollup-plugin-terser/node_modules/jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", @@ -17494,22 +16578,18 @@ "randombytes": "^2.1.0" } }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" }, "node_modules/rtl-css-js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2" } @@ -17538,14 +16618,15 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -17575,15 +16656,31 @@ ], "license": "MIT" }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -17649,15 +16746,16 @@ "license": "ISC" }, "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=v12.22.7" } }, "node_modules/scheduler": { @@ -17670,9 +16768,9 @@ } }, "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -17681,7 +16779,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -17689,15 +16787,15 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -17726,6 +16824,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "license": "MIT", "engines": { "node": ">=0.10.0" }, @@ -17753,9 +16852,9 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -17812,12 +16911,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -17956,10 +17049,25 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", + "license": "Unlicense", "engines": { "node": ">=6.9" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -17994,24 +17102,28 @@ } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -18020,6 +17132,66 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -18059,18 +17231,18 @@ "license": "MIT" }, "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -18107,15 +17279,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -18180,6 +17343,7 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } @@ -18205,6 +17369,13 @@ "node": ">=8" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", @@ -18215,6 +17386,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "license": "MIT", "dependencies": { "source-map": "0.5.6", "stackframe": "^1.3.4" @@ -18224,6 +17396,7 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -18232,6 +17405,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "license": "MIT", "dependencies": { "error-stack-parser": "^2.0.6", "stack-generator": "^2.0.5", @@ -18316,16 +17490,6 @@ "node": ">= 0.8.0" } }, - "node_modules/static-eval/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/static-eval/node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -18347,17 +17511,12 @@ "node": ">= 0.8" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "dev": true, + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -18381,18 +17540,6 @@ "node": ">=10" } }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", @@ -18434,64 +17581,45 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "license": "MIT", + "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-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -18500,16 +17628,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -18519,15 +17660,19 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -18564,18 +17709,15 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/strip-ansi-cjs": { @@ -18591,18 +17733,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -18634,6 +17764,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, "license": "MIT", "dependencies": { "min-indent": "^1.0.0" @@ -18670,10 +17801,19 @@ "webpack": "^5.0.0" } }, + "node_modules/style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, "node_modules/styled-components": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", - "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.14.tgz", + "integrity": "sha512-KtfwhU5jw7UoxdM0g6XU9VZQFV4do+KrM8idiVCH5h4v49W+3p3yMe0icYwJgZQZepa5DbH04Qv8P0/RdcLcgg==", "license": "MIT", "dependencies": { "@emotion/is-prop-valid": "1.2.2", @@ -18698,33 +17838,11 @@ "react-dom": ">= 16.8.0" } }, - "node_modules/styled-components/node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } + "node_modules/styled-components/node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" }, "node_modules/styled-components/node_modules/tslib": { "version": "2.6.2", @@ -18749,9 +17867,10 @@ } }, "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.5.tgz", + "integrity": "sha512-K7npNOKGRYuhAFFzkzMGfxFDpN6gDwf8hcMiE+uveTVbBgm93HrNP3ZDUpKqzZ4pG7TP6fmb+EMAQPjq9FqqvA==", + "license": "MIT" }, "node_modules/sucrase": { "version": "3.35.0", @@ -18794,9 +17913,9 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", - "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -18809,9 +17928,6 @@ "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -18832,15 +17948,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-hyperlinks": { @@ -18856,27 +17972,6 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -18923,6 +18018,56 @@ "node": ">=4.0.0" } }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/svgo/node_modules/css-select": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", @@ -18935,6 +18080,19 @@ "nth-check": "^1.0.2" } }, + "node_modules/svgo/node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/svgo/node_modules/css-what": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", @@ -18973,6 +18131,43 @@ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "license": "BSD-2-Clause" }, + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "license": "CC0-1.0" + }, "node_modules/svgo/node_modules/nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", @@ -18982,6 +18177,18 @@ "boolbase": "~1.0.0" } }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -18995,33 +18202,33 @@ "license": "MIT" }, "node_modules/tailwindcss": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", - "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -19031,6 +18238,46 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/tailwindcss/node_modules/postcss": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -19096,9 +18343,9 @@ } }, "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -19114,16 +18361,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -19147,24 +18394,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -19222,6 +18451,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "license": "MIT", "engines": { "node": ">=10" } @@ -19232,21 +18462,76 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.75", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.75.tgz", + "integrity": "sha512-+lFzEXhpl7JXgWYaXcB6DqTYXbUArvrWAE/5ioq/X3CdWLbDjpPP4XTrQBmEJ91y3xbe4Fkw7Lxv4P3GWeJaNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.75" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.75", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.75.tgz", + "integrity": "sha512-AOvV5YYIAFFBfransBzSTyztkc3IMfz5Eq3YluaRiEu55nn43Fzaufx70UqEKYr8BoLCach4q8g/bg6e5+/aFw==", + "dev": true, + "license": "MIT" + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "license": "BSD-3-Clause" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -19262,7 +18547,8 @@ "node_modules/toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" }, "node_modules/toidentifier": { "version": "1.0.1", @@ -19274,39 +18560,39 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz", + "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "node": ">=16" } }, "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.1.1" + "punycode": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=18" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/tryer": { @@ -19318,7 +18604,8 @@ "node_modules/ts-easing": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", - "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", + "license": "Unlicense" }, "node_modules/ts-interface-checker": { "version": "0.1.13", @@ -19360,9 +18647,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/tsutils": { @@ -19408,9 +18695,9 @@ } }, "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -19433,30 +18720,30 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -19466,17 +18753,18 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -19486,17 +18774,17 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -19515,28 +18803,31 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19548,10 +18839,16 @@ "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", "license": "MIT" }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "license": "MIT", "engines": { "node": ">=4" @@ -19571,9 +18868,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "license": "MIT", "engines": { "node": ">=4" @@ -19588,6 +18885,60 @@ "node": ">=4" } }, + "node_modules/unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/unified/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -19624,11 +18975,18 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-find-after/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" + "node_modules/unist-util-find-after/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/unist-util-generated": { "version": "1.1.6", @@ -19641,28 +18999,32 @@ } }, "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0" + "@types/unist": "^2.0.2" }, "funding": { "type": "opencollective", @@ -19670,14 +19032,16 @@ } }, "node_modules/unist-util-stringify-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" }, "node_modules/unist-util-visit": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -19692,6 +19056,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -19701,15 +19066,31 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-parents/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/unist-util-visit-parents/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/unist-util-visit/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/unist-util-visit/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/universalify": { "version": "2.0.1", @@ -19746,9 +19127,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "funding": [ { "type": "opencollective", @@ -19765,8 +19146,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -19795,21 +19176,26 @@ } }, "node_modules/use-composed-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz", + "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==", "license": "MIT", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", "license": "MIT", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -19818,15 +19204,15 @@ } }, "node_modules/use-latest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", - "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz", + "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==", "license": "MIT", "dependencies": { "use-isomorphic-layout-effect": "^1.1.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -19899,6 +19285,15 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT" }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -19909,12 +19304,12 @@ } }, "node_modules/vfile": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz", - "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { @@ -19926,6 +19321,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -19935,15 +19331,245 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/vfile-message/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/vfile/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", + "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vite/node_modules/rollup": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.1.tgz", + "integrity": "sha512-z+aeEsOeEa3mEbS1Tjl6sAZ8NE3+AalQz1RJGj81M+fizusbdDMoEJwdJNHfaB40Scr4qNu+welOfes7maKonA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.32.1", + "@rollup/rollup-android-arm64": "4.32.1", + "@rollup/rollup-darwin-arm64": "4.32.1", + "@rollup/rollup-darwin-x64": "4.32.1", + "@rollup/rollup-freebsd-arm64": "4.32.1", + "@rollup/rollup-freebsd-x64": "4.32.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.1", + "@rollup/rollup-linux-arm-musleabihf": "4.32.1", + "@rollup/rollup-linux-arm64-gnu": "4.32.1", + "@rollup/rollup-linux-arm64-musl": "4.32.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.1", + "@rollup/rollup-linux-riscv64-gnu": "4.32.1", + "@rollup/rollup-linux-s390x-gnu": "4.32.1", + "@rollup/rollup-linux-x64-gnu": "4.32.1", + "@rollup/rollup-linux-x64-musl": "4.32.1", + "@rollup/rollup-win32-arm64-msvc": "4.32.1", + "@rollup/rollup-win32-ia32-msvc": "4.32.1", + "@rollup/rollup-win32-x64-msvc": "4.32.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/vitest": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", + "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.8", + "@vitest/mocker": "2.1.8", + "@vitest/pretty-format": "^2.1.8", + "@vitest/runner": "2.1.8", + "@vitest/snapshot": "2.1.8", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.8", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.8", + "@vitest/ui": "2.1.8", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } }, "node_modules/w3c-hr-time": { "version": "1.0.2", @@ -19956,15 +19582,16 @@ } }, "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, "license": "MIT", "dependencies": { - "xml-name-validator": "^3.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/walker": { @@ -19977,9 +19604,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -20015,27 +19642,28 @@ "license": "Apache-2.0" }, "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">=10.4" + "node": ">=12" } }, "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "license": "MIT", "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", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", @@ -20151,27 +19779,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-manifest-plugin": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", @@ -20188,15 +19795,6 @@ "webpack": "^4.44.2 || ^5.47.0" } }, - "node_modules/webpack-manifest-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", @@ -20283,24 +19881,16 @@ } }, "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, "license": "MIT", "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "iconv-lite": "0.6.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, "node_modules/whatwg-fetch": { @@ -20310,23 +19900,27 @@ "license": "MIT" }, "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "license": "MIT" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", + "dev": true, "license": "MIT", "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/which": { @@ -20345,39 +19939,43 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "license": "MIT", "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", + "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -20405,15 +20003,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -20423,6 +20022,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -20517,15 +20133,15 @@ } }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -20553,6 +20169,18 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/workbox-build/node_modules/source-map": { "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", @@ -20726,13 +20354,16 @@ "webpack": "^4.4.0 || ^5.9.0" } }, - "node_modules/workbox-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", + "node_modules/workbox-webpack-plugin/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { @@ -20790,96 +20421,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -20899,16 +20440,16 @@ } }, "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -20920,10 +20461,14 @@ } }, "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "license": "Apache-2.0" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } }, "node_modules/xmlchars": { "version": "2.2.0", diff --git a/webview-ui/package.json b/webview-ui/package.json index cc5beb6397..d955fba53c 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -3,34 +3,32 @@ "version": "0.1.0", "private": true, "dependencies": { - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.18.101", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", "fuse.js": "^7.0.0", + "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-remark": "^2.1.0", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "react-textarea-autosize": "^8.5.3", "react-use": "^17.5.1", "react-virtuoso": "^4.7.13", "rehype-highlight": "^7.0.0", "rewire": "^7.0.0", "styled-components": "^6.1.13", - "typescript": "^4.9.5", + "typescript": "^5.7.3", "web-vitals": "^2.1.4" }, + "overrides": { + "typescript": "^5.7.3" + }, "scripts": { "start": "react-scripts start", "build": "node ./scripts/build-react-no-split.js", - "test": "react-scripts test", + "test": "vitest run", + "test:watch": "vitest dev", "eject": "react-scripts eject" }, "eslintConfig": { @@ -52,6 +50,15 @@ ] }, "devDependencies": { - "@types/vscode-webview": "^1.57.5" + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^15.0.6", + "@testing-library/user-event": "^13.5.0", + "@types/vscode-webview": "^1.57.5", + "@types/jest": "^27.5.2", + "@types/node": "^20.x", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "jsdom": "^25.0.1", + "vitest": "^2.1.8" } } diff --git a/webview-ui/setupTests.js b/webview-ui/setupTests.js new file mode 100644 index 0000000000..e876ebe760 --- /dev/null +++ b/webview-ui/setupTests.js @@ -0,0 +1,2 @@ +import "@testing-library/jest-dom" +import "./matchMedia" diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index f06453aca9..0043ef330b 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -5,6 +5,7 @@ import ChatView from "./components/chat/ChatView" import HistoryView from "./components/history/HistoryView" import SettingsView from "./components/settings/SettingsView" import WelcomeView from "./components/welcome/WelcomeView" +import AccountView from "./components/account/AccountView" import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext" import { vscode } from "./utils/vscode" import McpView from "./components/mcp/McpView" @@ -14,6 +15,7 @@ const AppContent = () => { const [showSettings, setShowSettings] = useState(false) const [showHistory, setShowHistory] = useState(false) const [showMcp, setShowMcp] = useState(false) + const [showAccount, setShowAccount] = useState(false) const [showAnnouncement, setShowAnnouncement] = useState(false) const handleMessage = useCallback((e: MessageEvent) => { @@ -25,21 +27,31 @@ const AppContent = () => { setShowSettings(true) setShowHistory(false) setShowMcp(false) + setShowAccount(false) break case "historyButtonClicked": setShowSettings(false) setShowHistory(true) setShowMcp(false) + setShowAccount(false) break case "mcpButtonClicked": setShowSettings(false) setShowHistory(false) setShowMcp(true) + setShowAccount(false) + break + case "accountLoginClicked": + setShowSettings(false) + setShowHistory(false) + setShowMcp(false) + setShowAccount(true) break case "chatButtonClicked": setShowSettings(false) setShowHistory(false) setShowMcp(false) + setShowAccount(false) break } break @@ -68,6 +80,7 @@ const AppContent = () => { {showSettings && setShowSettings(false)} />} {showHistory && setShowHistory(false)} />} {showMcp && setShowMcp(false)} />} + {showAccount && setShowAccount(false)} />} {/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */} { @@ -75,7 +88,7 @@ const AppContent = () => { setShowMcp(false) setShowHistory(true) }} - isHidden={showSettings || showHistory || showMcp} + isHidden={showSettings || showHistory || showMcp || showAccount} showAnnouncement={showAnnouncement} hideAnnouncement={() => { setShowAnnouncement(false) diff --git a/webview-ui/src/components/account/AccountOptions.tsx b/webview-ui/src/components/account/AccountOptions.tsx new file mode 100644 index 0000000000..fc2c9ddd0c --- /dev/null +++ b/webview-ui/src/components/account/AccountOptions.tsx @@ -0,0 +1,15 @@ +import { memo } from "react" +import { vscode } from "../../utils/vscode" + +const AccountOptions = () => { + const handleAccountClick = () => { + vscode.postMessage({ type: "accountLoginClicked" }) + } + + // Call handleAccountClick immediately when component mounts + handleAccountClick() + + return null // This component doesn't render anything +} + +export default memo(AccountOptions) diff --git a/webview-ui/src/components/account/AccountView.tsx b/webview-ui/src/components/account/AccountView.tsx new file mode 100644 index 0000000000..d4d9ec5fb9 --- /dev/null +++ b/webview-ui/src/components/account/AccountView.tsx @@ -0,0 +1,83 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import { memo } from "react" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { vscode } from "../../utils/vscode" + +type AccountViewProps = { + onDone: () => void +} + +const AccountView = ({ onDone }: AccountViewProps) => { + const { isLoggedIn, userInfo } = useExtensionState() + + const handleLogin = () => { + vscode.postMessage({ type: "accountLoginClicked" }) + } + + const handleLogout = () => { + vscode.postMessage({ type: "accountLogoutClicked" }) + } + + return ( +
+
+

Account

+ Done +
+
+
+ {isLoggedIn ? ( + <> + {userInfo?.photoURL && ( + Profile + )} +
+ {userInfo?.displayName &&
Name: {userInfo.displayName}
} + {userInfo?.email &&
Email: {userInfo.email}
} +
+ Log out + + ) : ( + Log in to Cline + )} +
+
+
+ ) +} + +export default memo(AccountView) diff --git a/webview-ui/src/components/browser/BrowserSettingsMenu.tsx b/webview-ui/src/components/browser/BrowserSettingsMenu.tsx new file mode 100644 index 0000000000..092cc19af9 --- /dev/null +++ b/webview-ui/src/components/browser/BrowserSettingsMenu.tsx @@ -0,0 +1,235 @@ +import { VSCodeButton, VSCodeCheckbox, VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" +import React, { useRef, useState } from "react" +import { useClickAway } from "react-use" +import styled from "styled-components" +import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { vscode } from "../../utils/vscode" +import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" + +interface BrowserSettingsMenuProps { + disabled?: boolean + maxWidth?: number +} + +export const BrowserSettingsMenu: React.FC = ({ disabled = false, maxWidth }) => { + const { browserSettings } = useExtensionState() + const [showMenu, setShowMenu] = useState(false) + const [hasMouseEntered, setHasMouseEntered] = useState(false) + const containerRef = useRef(null) + const menuRef = useRef(null) + + useClickAway(containerRef, () => { + if (showMenu) { + setShowMenu(false) + setHasMouseEntered(false) + } + }) + + const handleMouseEnter = () => { + setHasMouseEntered(true) + } + + const handleMouseLeave = () => { + if (hasMouseEntered) { + setShowMenu(false) + setHasMouseEntered(false) + } + } + + const handleControlsMouseLeave = (e: React.MouseEvent) => { + const menuElement = menuRef.current + + if (menuElement && showMenu) { + const menuRect = menuElement.getBoundingClientRect() + + // If mouse is moving towards the menu, don't close it + if ( + e.clientY >= menuRect.top && + e.clientY <= menuRect.bottom && + e.clientX >= menuRect.left && + e.clientX <= menuRect.right + ) { + return + } + } + + setShowMenu(false) + setHasMouseEntered(false) + } + + const handleViewportChange = (event: Event) => { + const target = event.target as HTMLSelectElement + const selectedSize = BROWSER_VIEWPORT_PRESETS[target.value as keyof typeof BROWSER_VIEWPORT_PRESETS] + if (selectedSize) { + vscode.postMessage({ + type: "browserSettings", + browserSettings: { + ...browserSettings, + viewport: selectedSize, + }, + }) + } + } + + const updateHeadless = (headless: boolean) => { + vscode.postMessage({ + type: "browserSettings", + browserSettings: { + ...browserSettings, + headless, + }, + }) + } + + // const updateChromeType = (chromeType: BrowserSettings["chromeType"]) => { + // vscode.postMessage({ + // type: "browserSettings", + // browserSettings: { + // ...browserSettings, + // chromeType, + // }, + // }) + // } + + // const relaunchChromeDebugMode = () => { + // vscode.postMessage({ + // type: "relaunchChromeDebugMode", + // }) + // } + + return ( +
+ setShowMenu(!showMenu)} disabled={disabled}> + + + {showMenu && ( + + + {/* Headless Mode */} + updateHeadless((e.target as HTMLInputElement).checked)}> + Run in headless mode + + When enabled, Chrome will run in the background. + + + {/* + Chrome Executable + + updateChromeType((e.target as HTMLSelectElement).value as BrowserSettings["chromeType"]) + }> + Chromium (Auto-downloaded) + System Chrome + + + {browserSettings.chromeType === "system" ? ( + <> + Cline will use your personal browser. You must{" "} + { + e.preventDefault() + relaunchChromeDebugMode() + }}> + relaunch Chrome in debug mode + {" "} + to use this setting. + + ) : ( + "Cline will use a Chromium browser bundled with the extension." + )} + + */} + + + Viewport Size + + size.width === browserSettings.viewport.width && + size.height === browserSettings.viewport.height, + )?.[0] + } + onChange={(event) => handleViewportChange(event as Event)}> + {Object.entries(BROWSER_VIEWPORT_PRESETS).map(([name]) => ( + + {name} + + ))} + + + + )} +
+ ) +} + +const SettingsMenu = styled.div<{ maxWidth?: number }>` + position: absolute; + top: calc(100% + 8px); + right: -2px; + background: ${CODE_BLOCK_BG_COLOR}; + border: 1px solid var(--vscode-editorGroup-border); + padding: 8px; + border-radius: 3px; + z-index: 1000; + width: calc(100vw - 57px); + min-width: 0px; + max-width: ${(props) => (props.maxWidth ? `${props.maxWidth - 23}px` : "100vw")}; + + // Add invisible padding to create a safe hover zone + &::before { + content: ""; + position: absolute; + top: -14px; // Same as margin-top in the parent's top property + left: 0; + right: -6px; + height: 14px; + } + + &::after { + content: ""; + position: absolute; + top: -6px; + right: 6px; + width: 10px; + height: 10px; + background: ${CODE_BLOCK_BG_COLOR}; + border-left: 1px solid var(--vscode-editorGroup-border); + border-top: 1px solid var(--vscode-editorGroup-border); + transform: rotate(45deg); + z-index: 1; // Ensure arrow stays above the padding + } +` + +const SettingsGroup = styled.div` + &:not(:last-child) { + margin-bottom: 8px; + // padding-bottom: 8px; + border-bottom: 1px solid var(--vscode-editorGroup-border); + } +` + +const SettingsHeader = styled.div` + font-size: 11px; + font-weight: 600; + margin-bottom: 6px; + color: var(--vscode-foreground); +` + +const SettingsDescription = styled.div<{ isLast?: boolean }>` + font-size: 11px; + color: var(--vscode-descriptionForeground); + margin-bottom: ${(props) => (props.isLast ? "0" : "8px")}; +` + +export default BrowserSettingsMenu diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 11978135de..da528089a4 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -1,13 +1,12 @@ import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { memo } from "react" -// import VSCodeButtonLink from "./VSCodeButtonLink" -// import { getOpenRouterAuthUrl } from "./ApiOptions" -// import { vscode } from "../utils/vscode" +import { getAsVar, VSC_DESCRIPTION_FOREGROUND, VSC_INACTIVE_SELECTION_BACKGROUND } from "../../utils/vscStyles" interface AnnouncementProps { version: string hideAnnouncement: () => void } + /* You must update the latestAnnouncementId in ClineProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves. */ @@ -16,17 +15,14 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { return (
- +

@@ -34,37 +30,26 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {

  • - Auto-approve menu: You can now specify which tools require approval, set a max # of - auto-approved API requests, and enable system notifications for when Cline completes a task. -
  • -
  • - New diff editing for large files: Cline now uses an efficient search & replace approach when - modifying large files for faster, more reliable edits (no more " - {"// rest of code here"}" deletions). -
  • -
  • - .clinerules: Add a root-level .clinerules file to specify custom instructions - for the project. -
  • -
-

v2.2 Updates:

-
    -
  • - Add and configure{" "} - - MCP servers + Plan/Act mode toggle: Plan mode turns Cline into an architect that gathers information, asks clarifying + questions, and designs a solution. Switch back to Act mode to let him execute the plan!{" "} + + See a demo here. - by clicking the new {" "} - icon in the menu bar.
  • - Cline can also create custom tools–just say "add a tool that...", and watch him create the MCP - server and install it in the extension, ready to use in future tasks. + Quick API/model switching with a new popup menu under the chat field
  • - Try it yourself by asking Cline to "add a tool that gets the latest npm docs", or - - see a demo of MCP in action here. + VS Code LM API lets you use models from other extensions like GitHub Copilot +
  • +
  • + MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for + individual tools +
  • +
  • + In case you missed it, Cline now supports Checkpoints!{" "} + + See it in action here.
@@ -100,7 +85,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { Switch to OpenRouter
)} - +
  • Edit Cline's changes before accepting! When he creates or edits a file, you can modify his changes directly in the right side of the diff view (+ hover over the 'Revert Block' arrow button in @@ -118,15 +103,19 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {

    - Join + Join our{" "} - discord.gg/cline + discord + {" "} + or{" "} + + r/cline for more updates!

    diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index dda2a5ac3a..68863a8fd2 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -4,6 +4,7 @@ import styled from "styled-components" import { useExtensionState } from "../../context/ExtensionStateContext" import { AutoApprovalSettings } from "../../../../src/shared/AutoApprovalSettings" import { vscode } from "../../utils/vscode" +import { getAsVar, VSC_FOREGROUND, VSC_TITLEBAR_INACTIVE_FOREGROUND, VSC_DESCRIPTION_FOREGROUND } from "../../utils/vscStyles" interface AutoApproveMenuProps { style?: React.CSSProperties @@ -128,7 +129,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { padding: "0 15px", userSelect: "none", borderTop: isExpanded - ? `0.5px solid color-mix(in srgb, var(--vscode-titleBar-inactiveForeground) 20%, transparent)` + ? `0.5px solid color-mix(in srgb, ${getAsVar(VSC_TITLEBAR_INACTIVE_FOREGROUND)} 20%, transparent)` : "none", overflowY: "auto", ...style, @@ -157,7 +158,9 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { } }}> { @@ -166,7 +169,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { // }} onClick={(e) => { /* - vscode web toolkit bug: when changing the value of a vscodecheckbox programatically, it will call its onChange with stale state. This led to updateEnabled being called with an old vesion of autoApprovalSettings, effectively undoing the state change that was triggered by the last action being unchecked. A simple workaround is to just not use onChange and intead use onClick. We are lucky this is a checkbox and the newvalue is simply opposite of current state. + vscode web toolkit bug: when changing the value of a vscodecheckbox programmatically, it will call its onChange with stale state. This led to updateEnabled being called with an old version of autoApprovalSettings, effectively undoing the state change that was triggered by the last action being unchecked. A simple workaround is to just not use onChange and instead use onClick. We are lucky this is a checkbox and the newvalue is simply opposite of current state. */ if (!hasEnabledActions) return e.stopPropagation() // stops click from bubbling up to the parent, in this case stopping the expanding/collapsing @@ -182,7 +185,13 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { setIsExpanded((prev) => !prev) } }}> - Auto-approve: + + Auto-approve: + {
    - Auto-approve allows Cline to perform the following actions without asking for permission. Please - use with caution and only enable if you understand the risks. + Auto-approve allows Cline to perform the following actions without asking for permission. Please use with + caution and only enable if you understand the risks.
    {ACTION_METADATA.map((action) => (
    @@ -224,7 +233,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
    {action.description} @@ -234,7 +243,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
    { gap: "8px", marginTop: "10px", marginBottom: "8px", - color: "var(--vscode-foreground)", + color: getAsVar(VSC_FOREGROUND), }}> Max Requests: { }} onKeyDown={(e) => { // Prevent non-numeric keys (except for backspace, delete, arrows) - if ( - !/^\d$/.test(e.key) && - !["Backspace", "Delete", "ArrowLeft", "ArrowRight"].includes(e.key) - ) { + if (!/^\d$/.test(e.key) && !["Backspace", "Delete", "ArrowLeft", "ArrowRight"].includes(e.key)) { e.preventDefault() } }} @@ -275,12 +281,11 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
    - Cline will automatically make this many API requests before asking for approval to proceed with - the task. + Cline will automatically make this many API requests before asking for approval to proceed with the task.
    {
    - Receive system notifications when Cline requires approval to proceed or when a task is - completed. + Receive system notifications when Cline requires approval to proceed or when a task is completed.
    @@ -311,12 +315,12 @@ const CollapsibleSection = styled.div<{ isHovered?: boolean }>` display: flex; align-items: center; gap: 4px; - color: ${(props) => (props.isHovered ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")}; + color: ${(props) => (props.isHovered ? getAsVar(VSC_FOREGROUND) : getAsVar(VSC_DESCRIPTION_FOREGROUND))}; flex: 1; min-width: 0; &:hover { - color: var(--vscode-foreground); + color: ${getAsVar(VSC_FOREGROUND)}; } ` diff --git a/webview-ui/src/components/chat/BrowserSessionRow.tsx b/webview-ui/src/components/chat/BrowserSessionRow.tsx index 60320fd387..7153cb7f21 100644 --- a/webview-ui/src/components/chat/BrowserSessionRow.tsx +++ b/webview-ui/src/components/chat/BrowserSessionRow.tsx @@ -1,16 +1,17 @@ import deepEqual from "fast-deep-equal" import React, { memo, useEffect, useMemo, useRef, useState } from "react" import { useSize } from "react-use" -import { - BrowserAction, - BrowserActionResult, - ClineMessage, - ClineSayBrowserAction, -} from "../../../../src/shared/ExtensionMessage" +import { BrowserAction, BrowserActionResult, ClineMessage, ClineSayBrowserAction } from "../../../../src/shared/ExtensionMessage" import { vscode } from "../../utils/vscode" import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import { ChatRowContent, ProgressIndicator } from "./ChatRow" import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" +import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls" +import { findLast } from "../../../../src/shared/array" +import { BrowserSettingsMenu } from "../browser/BrowserSettingsMenu" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings" interface BrowserSessionRowProps { messages: ClineMessage[] @@ -23,6 +24,7 @@ interface BrowserSessionRowProps { const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { const { messages, isLast, onHeightChange, lastModifiedMessage } = props + const { browserSettings } = useExtensionState() const prevHeightRef = useRef(0) const [maxActionHeight, setMaxActionHeight] = useState(0) const [consoleLogsExpanded, setConsoleLogsExpanded] = useState(false) @@ -98,11 +100,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { // Reset for next page currentStateMessages = [] nextActionMessages = [] - } else if ( - message.say === "api_req_started" || - message.say === "text" || - message.say === "browser_action" - ) { + } else if (message.say === "api_req_started" || message.say === "text" || message.say === "browser_action") { // These messages lead to the next result, so they should always go in nextActionMessages nextActionMessages.push(message) } else { @@ -137,19 +135,20 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { // Get initial URL from launch message const initialUrl = useMemo(() => { - const launchMessage = messages.find( - (m) => m.ask === "browser_action_launch" || m.say === "browser_action_launch", - ) + const launchMessage = messages.find((m) => m.ask === "browser_action_launch" || m.say === "browser_action_launch") return launchMessage?.text || "" }, [messages]) const isAutoApproved = useMemo(() => { - const launchMessage = messages.find( - (m) => m.ask === "browser_action_launch" || m.say === "browser_action_launch", - ) + const launchMessage = messages.find((m) => m.ask === "browser_action_launch" || m.say === "browser_action_launch") return launchMessage?.say === "browser_action_launch" }, [messages]) + const lastCheckpointMessageTs = useMemo(() => { + const lastCheckpointMessage = findLast(messages, (m) => m.lastCheckpointHash !== undefined) + return lastCheckpointMessage?.ts + }, [messages]) + // Find the latest available URL and screenshot const latestState = useMemo(() => { for (let i = pages.length - 1; i >= 0; i--) { @@ -163,23 +162,30 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { } } } - return { url: undefined, mousePosition: undefined, consoleLogs: undefined, screenshot: undefined } + return { + url: undefined, + mousePosition: undefined, + consoleLogs: undefined, + screenshot: undefined, + } }, [pages]) const currentPage = pages[currentPageIndex] const isLastPage = currentPageIndex === pages.length - 1 + const defaultMousePosition = `${browserSettings.viewport.width * 0.7},${browserSettings.viewport.height * 0.5}` + // Use latest state if we're on the last page and don't have a state yet const displayState = isLastPage ? { url: currentPage?.currentState.url || latestState.url || initialUrl, - mousePosition: currentPage?.currentState.mousePosition || latestState.mousePosition || "700,400", + mousePosition: currentPage?.currentState.mousePosition || latestState.mousePosition || defaultMousePosition, consoleLogs: currentPage?.currentState.consoleLogs, screenshot: currentPage?.currentState.screenshot || latestState.screenshot, } : { url: currentPage?.currentState.url || initialUrl, - mousePosition: currentPage?.currentState.mousePosition || "700,400", + mousePosition: currentPage?.currentState.mousePosition || defaultMousePosition, consoleLogs: currentPage?.currentState.consoleLogs, screenshot: currentPage?.currentState.screenshot, } @@ -187,12 +193,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { const [actionContent, { height: actionHeight }] = useSize(
    {currentPage?.nextAction?.messages.map((message) => ( - + ))} {!isBrowsing && messages.some((m) => m.say === "browser_action_result") && currentPageIndex === 0 && ( @@ -230,15 +231,37 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { // Use latest click position while browsing, otherwise use display state const mousePosition = isBrowsing ? latestClickPosition || displayState.mousePosition : displayState.mousePosition + let shouldShowCheckpoints = true + if (isLast) { + shouldShowCheckpoints = lastModifiedMessage?.ask === "resume_completed_task" || lastModifiedMessage?.ask === "resume_task" + } + + const shouldShowSettings = useMemo(() => { + const lastMessage = messages[messages.length - 1] + return lastMessage?.ask === "browser_action_launch" || lastMessage?.say === "browser_action_launch" + }, [messages]) + + // Calculate maxWidth + const maxWidth = browserSettings.viewport.width < BROWSER_VIEWPORT_PRESETS["Small Desktop (900x600)"].width ? 200 : undefined + const [browserSessionRow, { height }] = useSize( -
    -
    + +
    {isBrowsing ? ( ) : ( + style={{ + color: "var(--vscode-foreground)", + marginBottom: "-1.5px", + }}> )} <>{isAutoApproved ? "Cline is using the browser:" : "Cline wants to use the browser:"} @@ -248,45 +271,51 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { style={{ borderRadius: 3, border: "1px solid var(--vscode-editorGroup-border)", - overflow: "hidden", + // overflow: "hidden", backgroundColor: CODE_BLOCK_BG_COLOR, - marginBottom: 10, + // marginBottom: 10, + maxWidth, + margin: "0 auto 10px auto", // Center the container }}> {/* URL Bar */}
    - {displayState.url || "http"} +
    + {displayState.url || "http"} +
    +
    {/* Screenshot Area */}
    @@ -320,7 +349,10 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { }}>
    )} @@ -328,8 +360,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { @@ -345,7 +377,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { display: "flex", alignItems: "center", gap: "4px", - width: "100%", + // width: "100%", justifyContent: "flex-start", cursor: "pointer", padding: `9px 8px ${consoleLogsExpanded ? 0 : 8}px 8px`, @@ -390,7 +422,9 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
    )} -
    , + + {shouldShowCheckpoints && } + , ) // Height change effect @@ -490,15 +524,7 @@ const BrowserSessionRowContent = ({ } } -const BrowserActionBox = ({ - action, - coordinate, - text, -}: { - action: BrowserAction - coordinate?: string - text?: string -}) => { +const BrowserActionBox = ({ action, coordinate, text }: { action: BrowserAction; coordinate?: string; text?: string }) => { const getBrowserActionText = (action: BrowserAction, coordinate?: string, text?: string) => { switch (action) { case "launch": @@ -564,4 +590,13 @@ const BrowserCursor: React.FC<{ style?: React.CSSProperties }> = ({ style }) => ) } +const BrowserSessionRowContainer = styled.div` + padding: 10px 6px 10px 15px; + position: relative; + + &:hover ${CheckpointControls} { + opacity: 1; + } +` + export default BrowserSessionRow diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fdc53de453..59d40936f1 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -1,25 +1,39 @@ import { VSCodeBadge, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react" import deepEqual from "fast-deep-equal" -import React, { memo, useEffect, useMemo, useRef } from "react" -import { useSize } from "react-use" +import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react" +import { useEvent, useSize } from "react-use" +import styled from "styled-components" import { ClineApiReqInfo, ClineAskUseMcpServer, ClineMessage, ClineSayTool, + COMPLETION_RESULT_CHANGES_FLAG, + ExtensionMessage, } from "../../../../src/shared/ExtensionMessage" import { COMMAND_OUTPUT_STRING, COMMAND_REQ_APP_STRING } from "../../../../src/shared/combineCommandSequences" import { useExtensionState } from "../../context/ExtensionStateContext" import { findMatchingResourceOrTemplate } from "../../utils/mcp" import { vscode } from "../../utils/vscode" -import CodeAccordian, { removeLeadingNonAlphanumeric } from "../common/CodeAccordian" +import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls" +import CodeAccordian, { cleanPathPrefix } from "../common/CodeAccordian" import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import MarkdownBlock from "../common/MarkdownBlock" +import SuccessButton from "../common/SuccessButton" import Thumbnails from "../common/Thumbnails" import McpResourceRow from "../mcp/McpResourceRow" import McpToolRow from "../mcp/McpToolRow" import { highlightMentions } from "./TaskHeader" +const ChatRowContainer = styled.div` + padding: 10px 6px 10px 15px; + position: relative; + + &:hover ${CheckpointControls} { + opacity: 1; + } +` + interface ChatRowProps { message: ClineMessage isExpanded: boolean @@ -33,18 +47,33 @@ interface ChatRowContentProps extends Omit {} const ChatRow = memo( (props: ChatRowProps) => { - const { isLast, onHeightChange, message } = props + const { isLast, onHeightChange, message, lastModifiedMessage } = props // Store the previous height to compare with the current height // This allows us to detect changes without causing re-renders const prevHeightRef = useRef(0) + // NOTE: for tools that are interrupted and not responded to (approved or rejected), there won't be a checkpoint hash + let shouldShowCheckpoints = + message.lastCheckpointHash != null && + (message.say === "tool" || + message.ask === "tool" || + message.say === "command" || + message.ask === "command" || + message.say === "completion_result" || + message.ask === "completion_result" || + message.say === "use_mcp_server" || + message.ask === "use_mcp_server") + + if (shouldShowCheckpoints && isLast) { + shouldShowCheckpoints = + lastModifiedMessage?.ask === "resume_completed_task" || lastModifiedMessage?.ask === "resume_task" + } + const [chatrow, { height }] = useSize( -
    + -
    , + {shouldShowCheckpoints && } + , ) useEffect(() => { @@ -69,14 +98,11 @@ const ChatRow = memo( export default ChatRow -export const ChatRowContent = ({ - message, - isExpanded, - onToggleExpand, - lastModifiedMessage, - isLast, -}: ChatRowContentProps) => { +export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessage, isLast }: ChatRowContentProps) => { const { mcpServers } = useExtensionState() + + const [seeNewChangesDisabled, setSeeNewChangesDisabled] = useState(false) + const [cost, apiReqCancelReason, apiReqStreamingFailedMessage] = useMemo(() => { if (message.text != null && message.say === "api_req_started") { const info: ClineApiReqInfo = JSON.parse(message.text) @@ -103,27 +129,48 @@ export const ChatRowContent = ({ const successColor = "var(--vscode-charts-green)" const cancelledColor = "var(--vscode-descriptionForeground)" + const handleMessage = useCallback((event: MessageEvent) => { + const message: ExtensionMessage = event.data + switch (message.type) { + case "relinquishControl": { + setSeeNewChangesDisabled(false) + break + } + } + }, []) + + useEvent("message", handleMessage) + const [icon, title] = useMemo(() => { switch (type) { case "error": return [ , + style={{ + color: errorColor, + marginBottom: "-1.5px", + }}>, Error, ] case "mistake_limit_reached": return [ , + style={{ + color: errorColor, + marginBottom: "-1.5px", + }}>, Cline is having trouble..., ] case "auto_approval_max_req_reached": return [ , + style={{ + color: errorColor, + marginBottom: "-1.5px", + }}>, Maximum Requests Reached, ] case "command": @@ -133,12 +180,13 @@ export const ChatRowContent = ({ ) : ( + style={{ + color: normalColor, + marginBottom: "-1.5px", + }}> ), - {message.type === "ask" - ? "Cline wants to execute this command:" - : "Cline executed this command:"} + {message.type === "ask" ? "Cline wants to execute this command:" : "Cline executed this command:"} , ] case "use_mcp_server": @@ -149,19 +197,21 @@ export const ChatRowContent = ({ ) : ( + style={{ + color: normalColor, + marginBottom: "-1.5px", + }}> ), {message.type === "ask" ? ( <> - Cline wants to{" "} - {mcpServerUse.type === "use_mcp_tool" ? "use a tool" : "access a resource"} on the{" "} + Cline wants to {mcpServerUse.type === "use_mcp_tool" ? "use a tool" : "access a resource"} on the{" "} {mcpServerUse.serverName} MCP server: ) : ( <> - Cline {mcpServerUse.type === "use_mcp_tool" ? "used a tool" : "accessed a resource"} on - the {mcpServerUse.serverName} MCP server: + Cline {mcpServerUse.type === "use_mcp_tool" ? "used a tool" : "accessed a resource"} on the{" "} + {mcpServerUse.serverName} MCP server: )} , @@ -170,7 +220,10 @@ export const ChatRowContent = ({ return [ , + style={{ + color: successColor, + marginBottom: "-1.5px", + }}>, Task Completed, ] case "api_req_started": @@ -208,9 +261,21 @@ export const ChatRowContent = ({ ), apiReqCancelReason != null ? ( apiReqCancelReason === "user_cancelled" ? ( - API Request Cancelled + + API Request Cancelled + ) : ( - API Streaming Failed + + API Streaming Failed + ) ) : cost != null ? ( API Request @@ -224,7 +289,10 @@ export const ChatRowContent = ({ return [ , + style={{ + color: normalColor, + marginBottom: "-1.5px", + }}>, Cline has a question:, ] default: @@ -245,7 +313,7 @@ export const ChatRowContent = ({ display: "flex", alignItems: "center", gap: "10px", - marginBottom: "10px", + marginBottom: "12px", } const pStyle: React.CSSProperties = { @@ -266,7 +334,10 @@ export const ChatRowContent = ({ const toolIcon = (name: string) => ( + style={{ + color: "var(--vscode-foreground)", + marginBottom: "-1.5px", + }}> ) switch (tool.tool) { @@ -276,9 +347,7 @@ export const ChatRowContent = ({
    {toolIcon("edit")} - {message.type === "ask" - ? "Cline wants to edit this file:" - : "Cline is editing this file:"} + {message.type === "ask" ? "Cline wants to edit this file:" : "Cline is editing this file:"}
    {toolIcon("new-file")} - {message.type === "ask" - ? "Cline wants to create a new file:" - : "Cline is creating a new file:"} + {message.type === "ask" ? "Cline wants to create a new file:" : "Cline is creating a new file:"}
    { - vscode.postMessage({ type: "openFile", text: tool.content }) + vscode.postMessage({ + type: "openFile", + text: tool.content, + }) }}> {tool.path?.startsWith(".") && .} - {removeLeadingNonAlphanumeric(tool.path ?? "") + "\u200E"} + {cleanPathPrefix(tool.path ?? "") + "\u200E"}
    + style={{ + fontSize: 13.5, + margin: "1px 0", + }}>
    @@ -564,7 +637,7 @@ export const ChatRowContent = ({ gap: 10, padding: 8, fontSize: "12px", - color: "var(--vscode-errorForeground)", + color: "var(--vscode-editorWarning-foreground)", }}> The model has determined this command requires explicit approval. @@ -612,14 +685,19 @@ export const ChatRowContent = ({ {useMcpServer.type === "use_mcp_tool" && ( <> - tool.name === useMcpServer.toolName) - ?.description || "", - }} - /> +
    e.stopPropagation()}> + tool.name === useMcpServer.toolName)?.description || "", + autoApprove: + server?.tools?.find((tool) => tool.name === useMcpServer.toolName)?.autoApprove || + false, + }} + serverName={useMcpServer.serverName} + /> +
    {useMcpServer.arguments && useMcpServer.arguments !== "{}" && (
    -
    +
    {icon} {title} - {/* Need to render this everytime since it affects height of row by 2px */} - 0 ? 1 : 0 }}> + {/* Need to render this every time since it affects height of row by 2px */} + 0 ? 1 : 0, + }}> ${Number(cost || 0)?.toFixed(4)}
    @@ -679,7 +763,11 @@ export const ChatRowContent = ({
    {((cost == null && apiRequestFailedMessage) || apiReqStreamingFailedMessage) && ( <> -

    +

    {apiRequestFailedMessage || apiReqStreamingFailedMessage} {apiRequestFailedMessage?.toLowerCase().includes("powershell") && ( <> @@ -688,7 +776,10 @@ export const ChatRowContent = ({ It seems like you're having Windows PowerShell issues, please see this{" "} + style={{ + color: "inherit", + textDecoration: "underline", + }}> troubleshooting guide . @@ -751,6 +842,62 @@ export const ChatRowContent = ({

    ) + case "reasoning": + return ( + <> + {message.text && ( +
    + {isExpanded ? ( +
    + + Reasoning + + + {message.text} +
    + ) : ( +
    + Reasoning: + + {message.text + "\u200E"} + + +
    + )} +
    + )} + + ) case "user_feedback": return (
    )} -

    {message.text}

    +

    + {message.text} +

    ) case "diff_error": @@ -808,7 +961,12 @@ export const ChatRowContent = ({ borderRadius: 3, fontSize: 12, }}> -
    +
    - Diff Edit Failed + + Diff Edit Failed +
    - This usually happens when the model uses search patterns that don't match anything - in the file. Retrying... + This usually happens when the model uses search patterns that don't match anything in the + file. Retrying...
    ) case "completion_result": + const hasChanges = message.text?.endsWith(COMPLETION_RESULT_CHANGES_FLAG) ?? false + const text = hasChanges ? message.text?.slice(0, -COMPLETION_RESULT_CHANGES_FLAG.length) : message.text return ( <> -
    +
    {icon} {title}
    -
    - +
    +
    + {message.partial !== true && hasChanges && ( +
    + { + setSeeNewChangesDisabled(true) + vscode.postMessage({ + type: "taskCompletionViewChanges", + number: message.ts, + }) + }} + style={{ + width: "100%", + cursor: seeNewChangesDisabled ? "wait" : "pointer", + }}> + + See new changes + +
    + )} ) case "shell_integration_warning": @@ -849,7 +1043,12 @@ export const ChatRowContent = ({ borderRadius: 3, fontSize: 12, }}> -
    +
    - + Shell Integration Unavailable
    Cline won't be able to view the command's output. Please update VSCode ( - CMD/CTRL + Shift + P → "Update") and make sure you're using a supported - shell: zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → - "Terminal: Select Default Profile").{" "} + CMD/CTRL + Shift + P → "Update") and make sure you're using a supported shell: + zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → "Terminal: Select Default + Profile").{" "} + style={{ + color: "inherit", + textDecoration: "underline", + }}> Still having trouble?
    @@ -921,7 +1127,13 @@ export const ChatRowContent = ({ {icon} {title}
    -

    {message.text}

    +

    + {message.text} +

    ) case "auto_approval_max_req_reached": @@ -931,19 +1143,59 @@ export const ChatRowContent = ({ {icon} {title}
    -

    {message.text}

    +

    + {message.text} +

    ) case "completion_result": if (message.text) { + // FIXME: is this ever even used? + const hasChanges = message.text.endsWith(COMPLETION_RESULT_CHANGES_FLAG) ?? false + const text = hasChanges ? message.text.slice(0, -COMPLETION_RESULT_CHANGES_FLAG.length) : message.text return (
    -
    +
    {icon} {title}
    -
    - +
    + + {message.partial !== true && hasChanges && ( +
    + { + setSeeNewChangesDisabled(true) + vscode.postMessage({ + type: "taskCompletionViewChanges", + number: message.ts, + }) + }}> + + See new changes + +
    + )}
    ) @@ -964,6 +1216,12 @@ export const ChatRowContent = ({
    ) + case "plan_mode_response": + return ( +
    + +
    + ) default: return null } @@ -987,7 +1245,13 @@ export const ProgressIndicator = () => ( const Markdown = memo(({ markdown }: { markdown?: string }) => { return ( -
    +
    ) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index f465942f36..fa8584f21f 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -1,5 +1,8 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react" import DynamicTextArea from "react-textarea-autosize" +import { useClickAway, useWindowSize } from "react-use" +import styled from "styled-components" import { mentionRegex, mentionRegexGlobal } from "../../../../src/shared/context-mentions" import { useExtensionState } from "../../context/ExtensionStateContext" import { @@ -9,9 +12,13 @@ import { removeMention, shouldShowContextMenu, } from "../../utils/context-mentions" +import { validateApiConfiguration, validateModelId } from "../../utils/validate" +import { vscode } from "../../utils/vscode" +import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" +import Thumbnails from "../common/Thumbnails" +import ApiOptions, { normalizeApiConfiguration } from "../settings/ApiOptions" import { MAX_IMAGES_PER_MESSAGE } from "./ChatView" import ContextMenu from "./ContextMenu" -import Thumbnails from "../common/Thumbnails" interface ChatTextAreaProps { inputValue: string @@ -26,6 +33,167 @@ interface ChatTextAreaProps { onHeightChange?: (height: number) => void } +const PLAN_MODE_COLOR = "var(--vscode-inputValidation-warningBorder)" + +const SwitchOption = styled.div<{ isActive: boolean }>` + padding: 2px 8px; + color: ${(props) => (props.isActive ? "white" : "var(--vscode-input-foreground)")}; + z-index: 1; + transition: color 0.2s ease; + font-size: 12px; + width: 50%; + text-align: center; + + &:hover { + background-color: ${(props) => (!props.isActive ? "var(--vscode-toolbar-hoverBackground)" : "transparent")}; + } +` + +const SwitchContainer = styled.div<{ disabled: boolean }>` + display: flex; + align-items: center; + background-color: var(--vscode-editor-background); + border: 1px solid var(--vscode-input-border); + border-radius: 12px; + overflow: hidden; + cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; + opacity: ${(props) => (props.disabled ? 0.5 : 1)}; + transform: scale(0.85); + transform-origin: right center; + margin-left: -10px; // compensate for the transform so flex spacing works + user-select: none; // Prevent text selection +` + +const Slider = styled.div<{ isAct: boolean; isPlan?: boolean }>` + position: absolute; + height: 100%; + width: 50%; + background-color: ${(props) => (props.isPlan ? PLAN_MODE_COLOR : "var(--vscode-focusBorder)")}; + transition: transform 0.2s ease; + transform: translateX(${(props) => (props.isAct ? "100%" : "0%")}); +` + +const ButtonGroup = styled.div` + display: flex; + align-items: center; + gap: 4px; + flex: 1; + min-width: 0; +` + +const ButtonContainer = styled.div` + display: flex; + align-items: center; + gap: 3px; + font-size: 10px; + white-space: nowrap; + min-width: 0; + width: 100%; +` + +const ControlsContainer = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + margin-top: -5px; + padding: 0px 15px 5px 15px; +` + +const ModelSelectorTooltip = styled.div` + position: fixed; + bottom: calc(100% + 9px); + left: 15px; + right: 15px; + background: ${CODE_BLOCK_BG_COLOR}; + border: 1px solid var(--vscode-editorGroup-border); + padding: 12px; + border-radius: 3px; + z-index: 1000; + max-height: calc(100vh - 100px); + overflow-y: auto; + overscroll-behavior: contain; + + // Add invisible padding for hover zone + &::before { + content: ""; + position: fixed; + bottom: ${(props) => `calc(100vh - ${props.menuPosition}px - 2px)`}; + left: 0; + right: 0; + height: 8px; + } + + // Arrow pointing down + &::after { + content: ""; + position: fixed; + bottom: ${(props) => `calc(100vh - ${props.menuPosition}px)`}; + right: ${(props) => props.arrowPosition}px; + width: 10px; + height: 10px; + background: ${CODE_BLOCK_BG_COLOR}; + border-right: 1px solid var(--vscode-editorGroup-border); + border-bottom: 1px solid var(--vscode-editorGroup-border); + transform: rotate(45deg); + z-index: -1; + } +` + +const ModelContainer = styled.div` + position: relative; + display: flex; + flex: 1; + min-width: 0; +` + +const ModelButtonWrapper = styled.div` + display: inline-flex; // Make it shrink to content + min-width: 0; // Allow shrinking + max-width: 100%; // Don't overflow parent +` + +const ModelDisplayButton = styled.a<{ isActive?: boolean; disabled?: boolean }>` + padding: 0px 0px; + height: 20px; + width: 100%; + min-width: 0; + cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; + text-decoration: ${(props) => (props.isActive ? "underline" : "none")}; + color: ${(props) => (props.isActive ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")}; + display: flex; + align-items: center; + font-size: 10px; + outline: none; + user-select: none; + opacity: ${(props) => (props.disabled ? 0.5 : 1)}; + pointer-events: ${(props) => (props.disabled ? "none" : "auto")}; + + &:hover, + &:focus { + color: ${(props) => (props.disabled ? "var(--vscode-descriptionForeground)" : "var(--vscode-foreground)")}; + text-decoration: ${(props) => (props.disabled ? "none" : "underline")}; + outline: none; + } + + &:active { + color: ${(props) => (props.disabled ? "var(--vscode-descriptionForeground)" : "var(--vscode-foreground)")}; + text-decoration: ${(props) => (props.disabled ? "none" : "underline")}; + outline: none; + } + + &:focus-visible { + outline: none; + } +` + +const ModelButtonContent = styled.div` + width: 100%; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +` + const ChatTextArea = forwardRef( ( { @@ -42,7 +210,7 @@ const ChatTextArea = forwardRef( }, ref, ) => { - const { filePaths } = useExtensionState() + const { filePaths, chatSettings, apiConfiguration, openRouterModels } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) const [textAreaBaseHeight, setTextAreaBaseHeight] = useState(undefined) @@ -57,6 +225,15 @@ const ChatTextArea = forwardRef( const [justDeletedSpaceAfterMention, setJustDeletedSpaceAfterMention] = useState(false) const [intendedCursorPosition, setIntendedCursorPosition] = useState(null) const contextMenuContainerRef = useRef(null) + const [showModelSelector, setShowModelSelector] = useState(false) + const modelSelectorRef = useRef(null) + const { width: viewportWidth, height: viewportHeight } = useWindowSize() + const buttonRef = useRef(null) + const [arrowPosition, setArrowPosition] = useState(0) + const [menuPosition, setMenuPosition] = useState(0) + + // Add a ref to track previous menu state + const prevShowModelSelector = useRef(showModelSelector) const queryItems = useMemo(() => { return [ @@ -72,10 +249,7 @@ const ChatTextArea = forwardRef( useEffect(() => { const handleClickOutside = (event: MouseEvent) => { - if ( - contextMenuContainerRef.current && - !contextMenuContainerRef.current.contains(event.target as Node) - ) { + if (contextMenuContainerRef.current && !contextMenuContainerRef.current.contains(event.target as Node)) { setShowContextMenu(false) } } @@ -116,11 +290,7 @@ const ChatTextArea = forwardRef( insertValue = "problems" } - const { newValue, mentionIndex } = insertMention( - textAreaRef.current.value, - cursorPosition, - insertValue, - ) + const { newValue, mentionIndex } = insertMention(textAreaRef.current.value, cursorPosition, insertValue) setInputValue(newValue) const newCursorPosition = newValue.indexOf(" ", mentionIndex + insertValue.length) + 1 @@ -162,20 +332,16 @@ const ChatTextArea = forwardRef( // Find selectable options (non-URL types) const selectableOptions = options.filter( (option) => - option.type !== ContextMenuOptionType.URL && - option.type !== ContextMenuOptionType.NoResults, + option.type !== ContextMenuOptionType.URL && option.type !== ContextMenuOptionType.NoResults, ) if (selectableOptions.length === 0) return -1 // No selectable options // Find the index of the next selectable option - const currentSelectableIndex = selectableOptions.findIndex( - (option) => option === options[prevIndex], - ) + const currentSelectableIndex = selectableOptions.findIndex((option) => option === options[prevIndex]) const newSelectableIndex = - (currentSelectableIndex + direction + selectableOptions.length) % - selectableOptions.length + (currentSelectableIndex + direction + selectableOptions.length) % selectableOptions.length // Find the index of the selected option in the original options array return options.findIndex((option) => option === selectableOptions[newSelectableIndex]) @@ -184,9 +350,7 @@ const ChatTextArea = forwardRef( } if ((event.key === "Enter" || event.key === "Tab") && selectedMenuIndex !== -1) { event.preventDefault() - const selectedOption = getContextMenuOptions(searchQuery, selectedType, queryItems)[ - selectedMenuIndex - ] + const selectedOption = getContextMenuOptions(searchQuery, selectedType, queryItems)[selectedMenuIndex] if ( selectedOption && selectedOption.type !== ContextMenuOptionType.URL && @@ -201,6 +365,7 @@ const ChatTextArea = forwardRef( const isComposing = event.nativeEvent?.isComposing ?? false if (event.key === "Enter" && !event.shiftKey && !isComposing) { event.preventDefault() + setIsTextAreaFocused(false) onSend() } @@ -212,7 +377,7 @@ const ChatTextArea = forwardRef( charBeforeCursor === " " || charBeforeCursor === "\n" || charBeforeCursor === "\r\n" const charAfterIsWhitespace = charAfterCursor === " " || charAfterCursor === "\n" || charAfterCursor === "\r\n" - // checks if char before cusor is whitespace after a mention + // checks if char before cursor is whitespace after a mention if ( charBeforeIsWhitespace && inputValue.slice(0, cursorPosition - 1).match(new RegExp(mentionRegex.source + "$")) // "$" is added to ensure the match occurs at the end of the string @@ -312,8 +477,7 @@ const ChatTextArea = forwardRef( if (urlRegex.test(pastedText.trim())) { e.preventDefault() const trimmedUrl = pastedText.trim() - const newValue = - inputValue.slice(0, cursorPosition) + trimmedUrl + " " + inputValue.slice(cursorPosition) + const newValue = inputValue.slice(0, cursorPosition) + trimmedUrl + " " + inputValue.slice(cursorPosition) setInputValue(newValue) const newCursorPosition = cursorPosition + trimmedUrl.length + 1 setCursorPosition(newCursorPosition) @@ -420,181 +584,505 @@ const ChatTextArea = forwardRef( [updateCursorPosition], ) + // Separate the API config submission logic + const submitApiConfig = useCallback(() => { + const apiValidationResult = validateApiConfiguration(apiConfiguration) + const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) + + if (!apiValidationResult && !modelIdValidationResult) { + vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) + } else { + vscode.postMessage({ type: "getLatestState" }) + } + }, [apiConfiguration, openRouterModels]) + + const onModeToggle = useCallback(() => { + // if (textAreaDisabled) return + let changeModeDelay = 0 + if (showModelSelector) { + // user has model selector open, so we should save it before switching modes + submitApiConfig() + changeModeDelay = 250 // necessary to let the api config update (we send message and wait for it to be saved) FIXME: this is a hack and we ideally should check for api config changes, then wait for it to be saved, before switching modes + } + setTimeout(() => { + const newMode = chatSettings.mode === "plan" ? "act" : "plan" + vscode.postMessage({ + type: "chatSettings", + chatSettings: { + mode: newMode, + }, + }) + // Focus the textarea after mode toggle with slight delay + setTimeout(() => { + textAreaRef.current?.focus() + }, 100) + }, changeModeDelay) + }, [chatSettings.mode, showModelSelector, submitApiConfig]) + + const handleContextButtonClick = useCallback(() => { + if (textAreaDisabled) return + + // Focus the textarea first + textAreaRef.current?.focus() + + // If input is empty, just insert @ + if (!inputValue.trim()) { + const event = { + target: { + value: "@", + selectionStart: 1, + }, + } as React.ChangeEvent + handleInputChange(event) + updateHighlights() + return + } + + // If input ends with space or is empty, just append @ + if (inputValue.endsWith(" ")) { + const event = { + target: { + value: inputValue + "@", + selectionStart: inputValue.length + 1, + }, + } as React.ChangeEvent + handleInputChange(event) + updateHighlights() + return + } + + // Otherwise add space then @ + const event = { + target: { + value: inputValue + " @", + selectionStart: inputValue.length + 2, + }, + } as React.ChangeEvent + handleInputChange(event) + updateHighlights() + }, [inputValue, textAreaDisabled, handleInputChange, updateHighlights]) + + // Use an effect to detect menu close + useEffect(() => { + if (prevShowModelSelector.current && !showModelSelector) { + // Menu was just closed + submitApiConfig() + } + prevShowModelSelector.current = showModelSelector + }, [showModelSelector, submitApiConfig]) + + // Remove the handleApiConfigSubmit callback + // Update click handler to just toggle the menu + const handleModelButtonClick = () => { + setShowModelSelector(!showModelSelector) + } + + // Update click away handler to just close menu + useClickAway(modelSelectorRef, () => { + setShowModelSelector(false) + }) + + // Get model display name + const modelDisplayName = useMemo(() => { + const { selectedProvider, selectedModelId } = normalizeApiConfiguration(apiConfiguration) + const unknownModel = "unknown" + if (!apiConfiguration) return unknownModel + switch (selectedProvider) { + case "anthropic": + case "openrouter": + return `${selectedProvider}:${selectedModelId}` + case "openai": + return `openai-compat:${selectedModelId}` + case "vscode-lm": + return `vscode-lm:${apiConfiguration.vsCodeLmModelSelector ? `${apiConfiguration.vsCodeLmModelSelector.vendor ?? ""}/${apiConfiguration.vsCodeLmModelSelector.family ?? ""}` : unknownModel}` + default: + return `${selectedProvider}:${selectedModelId}` + } + }, [apiConfiguration]) + + // Calculate arrow position and menu position based on button location + useEffect(() => { + if (showModelSelector && buttonRef.current) { + const buttonRect = buttonRef.current.getBoundingClientRect() + const buttonCenter = buttonRect.left + buttonRect.width / 2 + + // Calculate distance from right edge of viewport using viewport coordinates + const rightPosition = document.documentElement.clientWidth - buttonCenter - 5 + + setArrowPosition(rightPosition) + setMenuPosition(buttonRect.top + 1) // Added +1 to move menu down by 1px + } + }, [showModelSelector, viewportWidth, viewportHeight]) + + useEffect(() => { + if (!showModelSelector) { + // Attempt to save if possible + // NOTE: we cannot call this here since it will create an infinite loop between this effect and the callback since getLatestState will update state. Instead we should submitapiconfig when the menu is explicitly closed, rather than as an effect of showModelSelector changing. + // handleApiConfigSubmit() + + // Reset any active styling by blurring the button + const button = buttonRef.current?.querySelector("a") + if (button) { + button.blur() + } + } + }, [showModelSelector]) + + /** + * Handles the drag over event to allow dropping. + * Prevents the default behavior to enable drop. + * + * @param {React.DragEvent} e - The drag event. + */ + const onDragOver = (e: React.DragEvent) => { + e.preventDefault() + } + + /** + * Handles the drop event for files and text. + * Processes dropped images and text, updating the state accordingly. + * + * @param {React.DragEvent} e - The drop event. + */ + const onDrop = async (e: React.DragEvent) => { + e.preventDefault() + + const files = Array.from(e.dataTransfer.files) + const text = e.dataTransfer.getData("text") + + if (text) { + handleTextDrop(text) + return + } + + const acceptedTypes = ["png", "jpeg", "webp"] + const imageFiles = files.filter((file) => { + const [type, subtype] = file.type.split("/") + return type === "image" && acceptedTypes.includes(subtype) + }) + + if (shouldDisableImages || imageFiles.length === 0) return + + const imageDataArray = await readImageFiles(imageFiles) + const dataUrls = imageDataArray.filter((dataUrl): dataUrl is string => dataUrl !== null) + + if (dataUrls.length > 0) { + setSelectedImages((prevImages) => [...prevImages, ...dataUrls].slice(0, MAX_IMAGES_PER_MESSAGE)) + } else { + console.warn("No valid images were processed") + } + } + + /** + * Handles the drop event for text. + * Inserts the dropped text at the current cursor position. + * + * @param {string} text - The dropped text. + */ + const handleTextDrop = (text: string) => { + const newValue = inputValue.slice(0, cursorPosition) + text + inputValue.slice(cursorPosition) + setInputValue(newValue) + const newCursorPosition = cursorPosition + text.length + setCursorPosition(newCursorPosition) + setIntendedCursorPosition(newCursorPosition) + } + + /** + * Reads image files and returns their data URLs. + * Uses FileReader to read the files as data URLs. + * + * @param {File[]} imageFiles - The image files to read. + * @returns {Promise<(string | null)[]>} - A promise that resolves to an array of data URLs or null values. + */ + const readImageFiles = (imageFiles: File[]): Promise<(string | null)[]> => { + return Promise.all( + imageFiles.map( + (file) => + new Promise((resolve) => { + const reader = new FileReader() + reader.onloadend = () => { + if (reader.error) { + console.error("Error reading file:", reader.error) + resolve(null) + } else { + const result = reader.result + resolve(typeof result === "string" ? result : null) + } + } + reader.readAsDataURL(file) + }), + ), + ) + } + return ( -
    - {showContextMenu && ( -
    - +
    + {showContextMenu && ( +
    + +
    + )} + {!isTextAreaFocused && ( +
    -
    - )} - {!isTextAreaFocused && ( + )} +
    + { + if (typeof ref === "function") { + ref(el) + } else if (ref) { + ref.current = el + } + textAreaRef.current = el + }} + value={inputValue} + disabled={textAreaDisabled} + onChange={(e) => { + handleInputChange(e) + updateHighlights() + }} + onKeyDown={handleKeyDown} + onKeyUp={handleKeyUp} + onFocus={() => setIsTextAreaFocused(true)} + onBlur={handleBlur} + onPaste={handlePaste} + onSelect={updateCursorPosition} + onMouseUp={updateCursorPosition} + onHeightChange={(height) => { + if (textAreaBaseHeight === undefined || height < textAreaBaseHeight) { + setTextAreaBaseHeight(height) + } + onHeightChange?.(height) + }} + placeholder={placeholderText} + maxRows={10} + autoFocus={true} + style={{ + width: "100%", + boxSizing: "border-box", + backgroundColor: "transparent", + color: "var(--vscode-input-foreground)", + //border: "1px solid var(--vscode-input-border)", + borderRadius: 2, + fontFamily: "var(--vscode-font-family)", + fontSize: "var(--vscode-editor-font-size)", + lineHeight: "var(--vscode-editor-line-height)", + resize: "none", + overflowX: "hidden", + overflowY: "scroll", + scrollbarWidth: "none", + // Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410) + // borderTop: "9px solid transparent", + borderLeft: 0, + borderRight: 0, + borderTop: 0, + borderBottom: `${thumbnailsHeight + 6}px solid transparent`, + borderColor: "transparent", + // borderRight: "54px solid transparent", + // borderLeft: "9px solid transparent", // NOTE: react-textarea-autosize doesn't calculate correct height when using borderLeft/borderRight so we need to use horizontal padding instead + // Instead of using boxShadow, we use a div with a border to better replicate the behavior when the textarea is focused + // boxShadow: "0px 0px 0px 1px var(--vscode-input-border)", + padding: "9px 28px 3px 9px", + cursor: textAreaDisabled ? "not-allowed" : undefined, + flex: 1, + zIndex: 1, + outline: isTextAreaFocused + ? `1px solid ${chatSettings.mode === "plan" ? PLAN_MODE_COLOR : "var(--vscode-focusBorder)"}` + : "none", + }} + onScroll={() => updateHighlights()} + /> + {selectedImages.length > 0 && ( + + )}
    - )} -
    - { - if (typeof ref === "function") { - ref(el) - } else if (ref) { - ref.current = el - } - textAreaRef.current = el - }} - value={inputValue} - disabled={textAreaDisabled} - onChange={(e) => { - handleInputChange(e) - updateHighlights() - }} - onKeyDown={handleKeyDown} - onKeyUp={handleKeyUp} - onFocus={() => setIsTextAreaFocused(true)} - onBlur={handleBlur} - onPaste={handlePaste} - onSelect={updateCursorPosition} - onMouseUp={updateCursorPosition} - onHeightChange={(height) => { - if (textAreaBaseHeight === undefined || height < textAreaBaseHeight) { - setTextAreaBaseHeight(height) - } - onHeightChange?.(height) - }} - placeholder={placeholderText} - maxRows={10} - autoFocus={true} - style={{ - width: "100%", - boxSizing: "border-box", - backgroundColor: "transparent", - color: "var(--vscode-input-foreground)", - //border: "1px solid var(--vscode-input-border)", - borderRadius: 2, - fontFamily: "var(--vscode-font-family)", - fontSize: "var(--vscode-editor-font-size)", - lineHeight: "var(--vscode-editor-line-height)", - resize: "none", - overflowX: "hidden", - overflowY: "scroll", - scrollbarWidth: "none", - // Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410) - // borderTop: "9px solid transparent", - borderLeft: 0, - borderRight: 0, - borderTop: 0, - borderBottom: `${thumbnailsHeight + 6}px solid transparent`, - borderColor: "transparent", - // borderRight: "54px solid transparent", - // borderLeft: "9px solid transparent", // NOTE: react-textarea-autosize doesn't calculate correct height when using borderLeft/borderRight so we need to use horizontal padding instead - // Instead of using boxShadow, we use a div with a border to better replicate the behavior when the textarea is focused - // boxShadow: "0px 0px 0px 1px var(--vscode-input-border)", - padding: "9px 49px 3px 9px", - cursor: textAreaDisabled ? "not-allowed" : undefined, - flex: 1, - zIndex: 1, - }} - onScroll={() => updateHighlights()} - /> - {selectedImages.length > 0 && ( - - )} -
    -
    + }}>
    + {/*
    { + if (!shouldDisableImages) { + onSelectImages() + } + }} + style={{ + marginRight: 5.5, + fontSize: 16.5, + }} + /> */} +
    { + if (!textAreaDisabled) { + setIsTextAreaFocused(false) + onSend() + } + }} + style={{ fontSize: 15 }}>
    +
    +
    +
    + + + + + + @ + {/* {showButtonText && Context} */} + + + + { if (!shouldDisableImages) { onSelectImages() } }} - style={{ - marginRight: 5.5, - fontSize: 16.5, - }} - /> -
    { - if (!textAreaDisabled) { - onSend() - } - }} - style={{ fontSize: 15 }}>
    -
    -
    + style={{ padding: "0px 0px", height: "20px" }}> + + + {/* {showButtonText && Images} */} + + + + + + { + // if (e.key === "Enter" || e.key === " ") { + // e.preventDefault() + // handleModelButtonClick() + // } + // }} + tabIndex={0}> + {modelDisplayName} + + + {showModelSelector && ( + + + + )} + + + + + + Plan + Act + +
    ) }, ) +// Update TypeScript interface for styled-component props +interface ModelSelectorTooltipProps { + arrowPosition: number + menuPosition: number +} + export default ChatTextArea diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 70a8fcfef6..bba6bb6fe1 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -5,6 +5,7 @@ import { useDeepCompareEffect, useEvent, useMount } from "react-use" import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" import styled from "styled-components" import { + ClineApiReqInfo, ClineAsk, ClineMessage, ClineSayBrowserAction, @@ -20,11 +21,11 @@ import { vscode } from "../../utils/vscode" import HistoryPreview from "../history/HistoryPreview" import { normalizeApiConfiguration } from "../settings/ApiOptions" import Announcement from "./Announcement" +import AutoApproveMenu from "./AutoApproveMenu" import BrowserSessionRow from "./BrowserSessionRow" import ChatRow from "./ChatRow" import ChatTextArea from "./ChatTextArea" import TaskHeader from "./TaskHeader" -import AutoApproveMenu from "./AutoApproveMenu" interface ChatViewProps { isHidden: boolean @@ -44,6 +45,20 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie // has to be after api_req_finished are all reduced into api_req_started messages const apiMetrics = useMemo(() => getApiMetrics(modifiedMessages), [modifiedMessages]) + const lastApiReqTotalTokens = useMemo(() => { + const getTotalTokensFromApiReqMessage = (msg: ClineMessage) => { + if (!msg.text) return 0 + const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse(msg.text) + return (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0) + } + const lastApiReqMessage = findLast(modifiedMessages, (msg) => { + if (msg.say !== "api_req_started") return false + return getTotalTokensFromApiReqMessage(msg) > 0 + }) + if (!lastApiReqMessage) return undefined + return getTotalTokensFromApiReqMessage(lastApiReqMessage) + }, [modifiedMessages]) + const [inputValue, setInputValue] = useState("") const textAreaRef = useRef(null) const [textAreaDisabled, setTextAreaDisabled] = useState(false) @@ -99,7 +114,14 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "followup": setTextAreaDisabled(isPartial) setClineAsk("followup") - setEnableButtons(isPartial) + setEnableButtons(false) + // setPrimaryButtonText(undefined) + // setSecondaryButtonText(undefined) + break + case "plan_mode_response": + setTextAreaDisabled(isPartial) + setClineAsk("plan_mode_response") + setEnableButtons(false) // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) break @@ -231,8 +253,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie const isStreaming = useMemo(() => { const isLastAsk = !!modifiedMessages.at(-1)?.ask // checking clineAsk isn't enough since messages effect may be called again for a tool for example, set clineAsk to its value, and if the next message is not an ask then it doesn't reset. This is likely due to how much more often we're updating messages as compared to before, and should be resolved with optimizations as it's likely a rendering bug. but as a final guard for now, the cancel button will show if the last message is not an ask - const isToolCurrentlyAsking = - isLastAsk && clineAsk !== undefined && enableButtons && primaryButtonText !== undefined + const isToolCurrentlyAsking = isLastAsk && clineAsk !== undefined && enableButtons && primaryButtonText !== undefined if (isToolCurrentlyAsking) { return false } @@ -263,6 +284,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie } else if (clineAsk) { switch (clineAsk) { case "followup": + case "plan_mode_response": case "tool": case "browser_action_launch": case "command": // user can provide feedback to a tool or command use @@ -313,7 +335,10 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "resume_task": case "mistake_limit_reached": case "auto_approval_max_req_reached": - vscode.postMessage({ type: "askResponse", askResponse: "yesButtonClicked" }) + vscode.postMessage({ + type: "askResponse", + askResponse: "yesButtonClicked", + }) break case "completion_result": case "resume_completed_task": @@ -347,7 +372,10 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "browser_action_launch": case "use_mcp_server": // responds to the API with a "This operation failed" and lets it try again - vscode.postMessage({ type: "askResponse", askResponse: "noButtonClicked" }) + vscode.postMessage({ + type: "askResponse", + askResponse: "noButtonClicked", + }) break } setTextAreaDisabled(true) @@ -389,9 +417,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "selectedImages": const newImages = message.images ?? [] if (newImages.length > 0) { - setSelectedImages((prevImages) => - [...prevImages, ...newImages].slice(0, MAX_IMAGES_PER_MESSAGE), - ) + setSelectedImages((prevImages) => [...prevImages, ...newImages].slice(0, MAX_IMAGES_PER_MESSAGE)) } break case "invoke": @@ -407,16 +433,9 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie break } } - // textAreaRef.current is not explicitly required here since react gaurantees that ref will be stable across re-renders, and we're not using its value but its reference. + // textAreaRef.current is not explicitly required here since react guarantees that ref will be stable across re-renders, and we're not using its value but its reference. }, - [ - isHidden, - textAreaDisabled, - enableButtons, - handleSendMessage, - handlePrimaryButtonClick, - handleSecondaryButtonClick, - ], + [isHidden, textAreaDisabled, enableButtons, handleSendMessage, handlePrimaryButtonClick, handleSecondaryButtonClick], ) useEvent("message", handleMessage) @@ -454,6 +473,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie switch (message.say) { case "api_req_finished": // combineApiRequests removes this from modifiedMessages anyways case "api_req_retried": // this message is used to update the latest api_req_started that the request was retried + case "deleted_api_reqs": // aggregated api_req metrics from deleted messages return false case "text": // Sometimes cline returns an empty text message, we don't want to render these. (We also use a say text for user messages, so in case they just sent images we still render that) @@ -474,13 +494,9 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie return ["browser_action_launch"].includes(message.ask!) } if (message.type === "say") { - return [ - "browser_action_launch", - "api_req_started", - "text", - "browser_action", - "browser_action_result", - ].includes(message.say!) + return ["browser_action_launch", "api_req_started", "text", "browser_action", "browser_action_result"].includes( + message.say!, + ) } return false } @@ -665,7 +681,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance const placeholderText = useMemo(() => { - const text = task ? "Type a message (@ to add context)..." : "Type your task here (@ to add context)..." + const text = task ? "Type a message..." : "Type your task here..." return text }, [task]) @@ -728,6 +744,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie cacheWrites={apiMetrics.totalCacheWrites} cacheReads={apiMetrics.totalCacheReads} totalCost={apiMetrics.totalCost} + lastApiReqTotalTokens={lastApiReqTotalTokens} onClose={handleTaskCloseButtonClick} /> ) : ( @@ -750,10 +767,10 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie style={{ display: "inline" }}> Claude 3.5 Sonnet's agentic coding capabilities, {" "} - I can handle complex software development tasks step-by-step. With tools that let me create - & edit files, explore complex projects, use the browser, and execute terminal commands - (after you grant permission), I can assist you in ways that go beyond code completion or - tech support. I can even use MCP to create new tools and extend my own capabilities. + I can handle complex software development tasks step-by-step. With tools that let me create & edit + files, explore complex projects, use the browser, and execute terminal commands (after you grant + permission), I can assist you in ways that go beyond code completion or tech support. I can even use + MCP to create new tools and extend my own capabilities.

    {taskHistory.length > 0 && } @@ -800,7 +817,10 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie Footer: () =>
    , // Add empty padding at the bottom }} // increasing top by 3_000 to prevent jumping around when user collapses a row - increaseViewportBy={{ top: 3_000, bottom: Number.MAX_SAFE_INTEGER }} // hack to make sure the last message is always rendered to get truly perfect scroll to bottom animation when new messages are added (Number.MAX_SAFE_INTEGER is safe for arithmetic operations, which is all virtuoso uses this value for in src/sizeRangeSystem.ts) + increaseViewportBy={{ + top: 3_000, + bottom: Number.MAX_SAFE_INTEGER, + }} // hack to make sure the last message is always rendered to get truly perfect scroll to bottom animation when new messages are added (Number.MAX_SAFE_INTEGER is safe for arithmetic operations, which is all virtuoso uses this value for in src/sizeRangeSystem.ts) data={groupedMessages} // messages is the raw format returned by extension, modifiedMessages is the manipulated structure that combines certain messages of related type, and visibleMessages is the filtered structure that removes messages that should not be rendered itemContent={itemContent} atBottomStateChange={(isAtBottom) => { diff --git a/webview-ui/src/components/chat/ContextMenu.tsx b/webview-ui/src/components/chat/ContextMenu.tsx index 7e56b332a5..25a7c0902f 100644 --- a/webview-ui/src/components/chat/ContextMenu.tsx +++ b/webview-ui/src/components/chat/ContextMenu.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useRef } from "react" import { ContextMenuOptionType, ContextMenuQueryItem, getContextMenuOptions } from "../../utils/context-mentions" -import { removeLeadingNonAlphanumeric } from "../common/CodeAccordian" +import { cleanPathPrefix } from "../common/CodeAccordian" interface ContextMenuProps { onSelect: (type: ContextMenuOptionType, value?: string) => void @@ -67,7 +67,7 @@ const ContextMenu: React.FC = ({ direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(option.value || "") + "\u200E"} + {cleanPathPrefix(option.value || "") + "\u200E"} ) @@ -153,7 +153,11 @@ const ContextMenu: React.FC = ({ }}> {renderOptionContent(option)}
    @@ -161,16 +165,23 @@ const ContextMenu: React.FC = ({ !option.value && ( )} {(option.type === ContextMenuOptionType.Problems || - ((option.type === ContextMenuOptionType.File || - option.type === ContextMenuOptionType.Folder) && + ((option.type === ContextMenuOptionType.File || option.type === ContextMenuOptionType.Folder) && option.value)) && ( )}
    diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 0b3f494b66..92e44e2e4d 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -1,12 +1,14 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import React, { memo, useEffect, useMemo, useRef, useState } from "react" import { useWindowSize } from "react-use" +import { mentionRegexGlobal } from "../../../../src/shared/context-mentions" import { ClineMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" +import { formatLargeNumber } from "../../utils/format" +import { formatSize } from "../../utils/size" import { vscode } from "../../utils/vscode" import Thumbnails from "../common/Thumbnails" -import { mentionRegexGlobal } from "../../../../src/shared/context-mentions" -import { formatLargeNumber } from "../../utils/format" +import { normalizeApiConfiguration } from "../settings/ApiOptions" interface TaskHeaderProps { task: ClineMessage @@ -16,6 +18,7 @@ interface TaskHeaderProps { cacheWrites?: number cacheReads?: number totalCost: number + lastApiReqTotalTokens?: number onClose: () => void } @@ -27,15 +30,19 @@ const TaskHeader: React.FC = ({ cacheWrites, cacheReads, totalCost, + lastApiReqTotalTokens, onClose, }) => { - const { apiConfiguration } = useExtensionState() + const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage } = useExtensionState() const [isTaskExpanded, setIsTaskExpanded] = useState(true) const [isTextExpanded, setIsTextExpanded] = useState(false) const [showSeeMore, setShowSeeMore] = useState(false) const textContainerRef = useRef(null) const textRef = useRef(null) + const { selectedModelInfo } = useMemo(() => normalizeApiConfiguration(apiConfiguration), [apiConfiguration]) + const contextWindow = selectedModelInfo?.contextWindow + /* When dealing with event listeners in React components that depend on state variables, we face a challenge. We want our listener to always use the most up-to-date version of a callback function that relies on current state, but we don't want to constantly add and remove event listeners as that function updates. This scenario often arises with resize listeners or other window events. Simply adding the listener in a useEffect with an empty dependency array risks using stale state, while including the callback in the dependencies can lead to unnecessary re-registrations of the listener. There are react hook libraries that provide a elegant solution to this problem by utilizing the useRef hook to maintain a reference to the latest callback function without triggering re-renders or effect re-runs. This approach ensures that our event listener always has access to the most current state while minimizing performance overhead and potential memory leaks from multiple listener registrations. Sources @@ -95,6 +102,7 @@ const TaskHeader: React.FC = ({ const isCostAvailable = useMemo(() => { return ( apiConfiguration?.apiProvider !== "openai" && + apiConfiguration?.apiProvider !== "vscode-lm" && apiConfiguration?.apiProvider !== "ollama" && apiConfiguration?.apiProvider !== "lmstudio" && apiConfiguration?.apiProvider !== "gemini" @@ -103,6 +111,68 @@ const TaskHeader: React.FC = ({ const shouldShowPromptCacheInfo = doesModelSupportPromptCache && apiConfiguration?.apiProvider !== "openrouter" + const ContextWindowComponent = ( + <> + {isTaskExpanded && contextWindow && ( +
    +
    + + {/* {windowWidth > 280 && windowWidth < 310 ? "Context:" : "Context Window:"} */} + Context Window: + +
    +
    + {formatLargeNumber(lastApiReqTotalTokens || 0)} +
    +
    +
    +
    + {formatLargeNumber(contextWindow)} +
    +
    +
    + )} + + ) + return (
    = ({ minWidth: 0, // This allows the div to shrink below its content size }} onClick={() => setIsTaskExpanded(!isTaskExpanded)}> -
    +
    = ({ flexGrow: 1, minWidth: 0, // This allows the div to shrink below its content size }}> - Task{!isTaskExpanded && ":"} - {!isTaskExpanded && ( - {highlightMentions(task.text, false)} - )} + + Task + {!isTaskExpanded && ":"} + + {!isTaskExpanded && {highlightMentions(task.text, false)}}
    {!isTaskExpanded && isCostAvailable && ( @@ -213,8 +289,7 @@ const TaskHeader: React.FC = ({ style={{ width: 30, height: "1.2em", - background: - "linear-gradient(to right, transparent, var(--vscode-badge-background))", + background: "linear-gradient(to right, transparent, var(--vscode-badge-background))", }} />
    = ({
    )} {task.images && task.images.length > 0 && } -
    +
    -
    +
    Tokens: - + {formatLargeNumber(tokensIn || 0)} - + {formatLargeNumber(tokensOut || 0)}
    - {!isCostAvailable && } + {!isCostAvailable && ( + + )}
    {shouldShowPromptCacheInfo && (cacheReads !== undefined || cacheWrites !== undefined) && ( -
    +
    Cache: - + +{formatLargeNumber(cacheWrites || 0)} - + {formatLargeNumber(cacheReads || 0)}
    )} + {ContextWindowComponent} {isCostAvailable && (
    -
    +
    API Cost: ${totalCost?.toFixed(4)}
    - + +
    + )} + {checkpointTrackerErrorMessage && ( +
    + + + {checkpointTrackerErrorMessage} + {checkpointTrackerErrorMessage.includes("Git must be installed to use checkpoints.") && ( + <> + {" "} + + See here for instructions. + + + )} +
    )}
    @@ -363,18 +529,41 @@ export const highlightMentions = (text?: string, withShadow = true) => { }) } -const ExportButton = () => ( +const DeleteButton: React.FC<{ + taskSize: string + taskId?: string +}> = ({ taskSize, taskId }) => ( vscode.postMessage({ type: "exportCurrentTask" })} - style={ - { - // marginBottom: "-2px", - // marginRight: "-2.5px", - } - }> -
    EXPORT
    + onClick={() => vscode.postMessage({ type: "deleteTaskWithId", text: taskId })} + style={{ padding: "0px 0px" }}> +
    + + {taskSize} +
    ) +// const ExportButton = () => ( +// vscode.postMessage({ type: "exportCurrentTask" })} +// style={ +// { +// // marginBottom: "-2px", +// // marginRight: "-2.5px", +// } +// }> +//
    EXPORT
    +//
    +// ) + export default memo(TaskHeader) diff --git a/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx new file mode 100644 index 0000000000..563a705590 --- /dev/null +++ b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx @@ -0,0 +1,39 @@ +import { render, screen, fireEvent } from "@testing-library/react" +import { describe, it, expect, vi } from "vitest" +import Announcement from "../Announcement" + +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ + useTheme: () => ({ themeType: "light" }), + VSCodeButton: (props: any) => , + VSCodeLink: ({ children }: { children: React.ReactNode }) => {children}, +})) + +describe("Announcement", () => { + const hideAnnouncement = vi.fn() + + it("renders the announcement with the correct version", () => { + render() + expect(screen.getByText(/New in v2.0/)).toBeInTheDocument() + }) + + it("calls hideAnnouncement when close button is clicked", () => { + render() + fireEvent.click(screen.getByRole("button")) + expect(hideAnnouncement).toHaveBeenCalled() + }) + + it("renders the mcp server improvements announcement", () => { + render() + expect(screen.getByText(/MCP server improvements:/)).toBeInTheDocument() + }) + + it("renders the 'See new changes' button feature", () => { + render() + expect(screen.getByText(/See it in action here./)).toBeInTheDocument() + }) + + it("renders the demo link", () => { + render() + expect(screen.getByText(/See a demo here./)).toBeInTheDocument() + }) +}) diff --git a/webview-ui/src/components/common/CheckpointControls.tsx b/webview-ui/src/components/common/CheckpointControls.tsx new file mode 100644 index 0000000000..fc514e594e --- /dev/null +++ b/webview-ui/src/components/common/CheckpointControls.tsx @@ -0,0 +1,268 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import { useCallback, useRef, useState } from "react" +import { useClickAway, useEvent } from "react-use" +import styled from "styled-components" +import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" +import { vscode } from "../../utils/vscode" +import { CODE_BLOCK_BG_COLOR } from "./CodeBlock" +import { ClineCheckpointRestore } from "../../../../src/shared/WebviewMessage" + +interface CheckpointOverlayProps { + messageTs?: number +} + +export const CheckpointOverlay = ({ messageTs }: CheckpointOverlayProps) => { + const [compareDisabled, setCompareDisabled] = useState(false) + const [restoreTaskDisabled, setRestoreTaskDisabled] = useState(false) + const [restoreWorkspaceDisabled, setRestoreWorkspaceDisabled] = useState(false) + const [restoreBothDisabled, setRestoreBothDisabled] = useState(false) + const [showRestoreConfirm, setShowRestoreConfirm] = useState(false) + const [hasMouseEntered, setHasMouseEntered] = useState(false) + const containerRef = useRef(null) + const tooltipRef = useRef(null) + + useClickAway(containerRef, () => { + if (showRestoreConfirm) { + setShowRestoreConfirm(false) + setHasMouseEntered(false) + } + }) + + const handleMessage = useCallback((event: MessageEvent) => { + const message: ExtensionMessage = event.data + switch (message.type) { + case "relinquishControl": { + setCompareDisabled(false) + setRestoreTaskDisabled(false) + setRestoreWorkspaceDisabled(false) + setRestoreBothDisabled(false) + setShowRestoreConfirm(false) + break + } + } + }, []) + + useEvent("message", handleMessage) + + const handleRestoreTask = () => { + setRestoreTaskDisabled(true) + vscode.postMessage({ + type: "checkpointRestore", + number: messageTs, + text: "task" satisfies ClineCheckpointRestore, + }) + } + + const handleRestoreWorkspace = () => { + setRestoreWorkspaceDisabled(true) + vscode.postMessage({ + type: "checkpointRestore", + number: messageTs, + text: "workspace" satisfies ClineCheckpointRestore, + }) + } + + const handleRestoreBoth = () => { + setRestoreBothDisabled(true) + vscode.postMessage({ + type: "checkpointRestore", + number: messageTs, + text: "taskAndWorkspace" satisfies ClineCheckpointRestore, + }) + } + + const handleMouseEnter = () => { + setHasMouseEntered(true) + } + + const handleMouseLeave = () => { + if (hasMouseEntered) { + setShowRestoreConfirm(false) + setHasMouseEntered(false) + } + } + + const handleControlsMouseLeave = (e: React.MouseEvent) => { + const tooltipElement = tooltipRef.current + + if (tooltipElement && showRestoreConfirm) { + const tooltipRect = tooltipElement.getBoundingClientRect() + + // If mouse is moving towards the tooltip, don't close it + if ( + e.clientY >= tooltipRect.top && + e.clientY <= tooltipRect.bottom && + e.clientX >= tooltipRect.left && + e.clientX <= tooltipRect.right + ) { + return + } + } + + setShowRestoreConfirm(false) + setHasMouseEntered(false) + } + + return ( + + { + setCompareDisabled(true) + vscode.postMessage({ + type: "checkpointDiff", + number: messageTs, + }) + }}> + + +
    + setShowRestoreConfirm(true)}> + + + {showRestoreConfirm && ( + + + + Restore Task and Workspace + +

    Restores the task and your project's files back to a snapshot taken at this point

    +
    + + + Restore Task Only + +

    Deletes messages after this point (does not affect workspace)

    +
    + + + Restore Workspace Only + +

    Restores your project's files to a snapshot taken at this point (task may become out of sync)

    +
    +
    + )} +
    +
    + ) +} + +export const CheckpointControls = styled.div` + position: absolute; + top: 3px; + right: 6px; + display: flex; + gap: 6px; + opacity: 0; + background-color: var(--vscode-sideBar-background); + padding: 3px 0 3px 3px; + + & > vscode-button, + & > div > vscode-button { + width: 24px; + height: 24px; + position: relative; + } + + & > vscode-button i, + & > div > vscode-button i { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + } +` + +const RestoreOption = styled.div` + &:not(:last-child) { + margin-bottom: 10px; + padding-bottom: 4px; + border-bottom: 1px solid var(--vscode-editorGroup-border); + } + + p { + margin: 0 0 2px 0; + color: var(--vscode-descriptionForeground); + font-size: 11px; + line-height: 14px; + } + + &:last-child p { + margin: 0 0 -2px 0; + } + + vscode-button { + width: 100%; + margin-bottom: 10px; + } +` + +const RestoreConfirmTooltip = styled.div` + position: absolute; + top: calc(100% - 0.5px); + right: 0; + background: ${CODE_BLOCK_BG_COLOR}; + border: 1px solid var(--vscode-editorGroup-border); + padding: 12px; + border-radius: 3px; + margin-top: 8px; + width: calc(100vw - 57px); + min-width: 0px; + max-width: 100vw; + z-index: 1000; + + // Add invisible padding to create a safe hover zone + &::before { + content: ""; + position: absolute; + top: -8px; // Same as margin-top + left: 0; + right: 0; + height: 8px; + } + + // Adjust arrow to be above the padding + &::after { + content: ""; + position: absolute; + top: -6px; + right: 6px; + width: 10px; + height: 10px; + background: ${CODE_BLOCK_BG_COLOR}; + border-left: 1px solid var(--vscode-editorGroup-border); + border-top: 1px solid var(--vscode-editorGroup-border); + transform: rotate(45deg); + z-index: 1; // Ensure arrow stays above the padding + } + + p { + margin: 0 0 6px 0; + color: var(--vscode-descriptionForeground); + font-size: 12px; + white-space: normal; + word-wrap: break-word; + } +` diff --git a/webview-ui/src/components/common/CodeAccordian.tsx b/webview-ui/src/components/common/CodeAccordian.tsx index 36f8fbc1f9..cb0c02bb42 100644 --- a/webview-ui/src/components/common/CodeAccordian.tsx +++ b/webview-ui/src/components/common/CodeAccordian.tsx @@ -20,7 +20,7 @@ We need to remove leading non-alphanumeric characters from the path in order for [^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric. The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character. */ -export const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "") +export const cleanPathPrefix = (path: string): string => path.replace(/^[^\u4e00-\u9fa5a-zA-Z0-9]+/, "") const CodeAccordian = ({ code, @@ -90,7 +90,7 @@ const CodeAccordian = ({ direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(path ?? "") + "\u200E"} + {cleanPathPrefix(path ?? "") + "\u200E"} )} diff --git a/webview-ui/src/components/common/CodeBlock.tsx b/webview-ui/src/components/common/CodeBlock.tsx index b00f641d5d..bc5c1fcbcf 100644 --- a/webview-ui/src/components/common/CodeBlock.tsx +++ b/webview-ui/src/components/common/CodeBlock.tsx @@ -120,7 +120,7 @@ const CodeBlock = memo(({ source, forceWrap = false }: CodeBlockProps) => { if (!node.lang) { node.lang = "javascript" } else if (node.lang.includes(".")) { - // if the langauge is a file, get the extension + // if the language is a file, get the extension node.lang = node.lang.split(".").slice(-1)[0] } }) diff --git a/webview-ui/src/components/common/SettingsButton.tsx b/webview-ui/src/components/common/SettingsButton.tsx new file mode 100644 index 0000000000..2f63240c71 --- /dev/null +++ b/webview-ui/src/components/common/SettingsButton.tsx @@ -0,0 +1,36 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" + +const StyledButton = styled(VSCodeButton)` + --settings-button-bg: var(--vscode-button-secondaryBackground); + --settings-button-hover: var(--vscode-button-secondaryHoverBackground); + --settings-button-active: var(--vscode-button-secondaryBackground); + + background-color: var(--settings-button-bg) !important; + border-color: var(--settings-button-bg) !important; + width: 100% !important; + + &:hover { + background-color: var(--settings-button-hover) !important; + border-color: var(--settings-button-hover) !important; + } + + &:active { + background-color: var(--settings-button-active) !important; + border-color: var(--settings-button-active) !important; + } + + i.codicon { + margin-right: 6px; + flex-shrink: 0; + font-size: 16px !important; + } +` + +interface SettingsButtonProps extends React.ComponentProps {} + +const SettingsButton: React.FC = (props) => { + return +} + +export default SettingsButton diff --git a/webview-ui/src/components/common/SuccessButton.tsx b/webview-ui/src/components/common/SuccessButton.tsx new file mode 100644 index 0000000000..51993462a3 --- /dev/null +++ b/webview-ui/src/components/common/SuccessButton.tsx @@ -0,0 +1,30 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" + +const StyledButton = styled(VSCodeButton)` + --success-button-bg: #176f2c; + --success-button-hover: #197f31; + --success-button-active: #156528; + + background-color: var(--success-button-bg) !important; + border-color: var(--success-button-bg) !important; + color: #ffffff !important; + + &:hover { + background-color: var(--success-button-hover) !important; + border-color: var(--success-button-hover) !important; + } + + &:active { + background-color: var(--success-button-active) !important; + border-color: var(--success-button-active) !important; + } +` + +interface SuccessButtonProps extends React.ComponentProps {} + +const SuccessButton: React.FC = (props) => { + return +} + +export default SuccessButton diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 08aca2a44d..06a2e9bc62 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -59,7 +59,10 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { }}> + style={{ + marginRight: "4px", + transform: "scale(0.9)", + }}> { .filter((item) => item.ts && item.task) .slice(0, 3) .map((item) => ( -
    handleHistorySelect(item.id)}> +
    handleHistorySelect(item.id)}>
    { }}> {item.task}
    -
    +
    - Tokens: ↑{formatLargeNumber(item.tokensIn || 0)} ↓ - {formatLargeNumber(item.tokensOut || 0)} + Tokens: ↑{formatLargeNumber(item.tokensIn || 0)} ↓{formatLargeNumber(item.tokensOut || 0)} {!!item.cacheWrites && ( <> @@ -130,7 +133,12 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => {
    ))} -
    +
    showHistoryView()} diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index 14b97c6d48..d50b4b39db 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -5,6 +5,7 @@ import { Virtuoso } from "react-virtuoso" import { memo, useMemo, useState, useEffect } from "react" import Fuse, { FuseResult } from "fuse.js" import { formatLargeNumber } from "../../utils/format" +import { formatSize } from "../../utils/size" type HistoryViewProps = { onDone: () => void @@ -136,11 +137,22 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { alignItems: "center", padding: "10px 17px 10px 20px", }}> -

    History

    +

    + History +

    Done
    -
    +
    {
    + style={{ + fontSize: 13, + marginTop: 2.5, + opacity: 0.8, + }}>
    {searchQuery && (
    { Oldest Most Expensive Most Tokens - + Most Relevant @@ -219,9 +232,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { style={{ cursor: "pointer", borderBottom: - index < taskHistory.length - 1 - ? "1px solid var(--vscode-panel-border)" - : "none", + index < taskHistory.length - 1 ? "1px solid var(--vscode-panel-border)" : "none", }} onClick={() => handleHistorySelect(item.id)}>
    { e.stopPropagation() handleDeleteHistoryItem(item.id) }} - className="delete-button"> - + className="delete-button" + style={{ padding: "0px 0px" }}> +
    + + {formatSize(item.size)} +
    { wordBreak: "break-word", overflowWrap: "anywhere", }} - dangerouslySetInnerHTML={{ __html: item.task }} + dangerouslySetInnerHTML={{ + __html: item.task, + }} /> -
    +
    { alignItems: "center", marginTop: -2, }}> -
    +
    { }}> API Cost: - + ${item.totalCost?.toFixed(4)}
    @@ -428,10 +465,7 @@ const ExportButton = ({ itemId }: { itemId: string }) => ( ) // https://gist.github.com/evenfrost/1ba123656ded32fb7a0cd4651efd4db0 -export const highlight = ( - fuseSearchResult: FuseResult[], - highlightClassName: string = "history-item-highlight", -) => { +export const highlight = (fuseSearchResult: FuseResult[], highlightClassName: string = "history-item-highlight") => { const set = (obj: Record, path: string, value: any) => { const pathValue = path.split(".") let i: number diff --git a/webview-ui/src/components/mcp/McpToolRow.tsx b/webview-ui/src/components/mcp/McpToolRow.tsx index c402d3413f..18619fe07f 100644 --- a/webview-ui/src/components/mcp/McpToolRow.tsx +++ b/webview-ui/src/components/mcp/McpToolRow.tsx @@ -1,19 +1,45 @@ +import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react" import { McpTool } from "../../../../src/shared/mcp" +import { vscode } from "../../utils/vscode" +import { useExtensionState } from "../../context/ExtensionStateContext" type McpToolRowProps = { tool: McpTool + serverName?: string } -const McpToolRow = ({ tool }: McpToolRowProps) => { +const McpToolRow = ({ tool, serverName }: McpToolRowProps) => { + const { autoApprovalSettings } = useExtensionState() + + const handleAutoApproveChange = () => { + if (!serverName) return + + vscode.postMessage({ + type: "toggleToolAutoApprove", + serverName, + toolName: tool.name, + autoApprove: !tool.autoApprove, + }) + } return (
    -
    - - {tool.name} +
    e.stopPropagation()}> +
    + + {tool.name} +
    + {serverName && autoApprovalSettings.enabled && autoApprovalSettings.actions.useMcp && ( + + Auto-approve + + )}
    {tool.description && (
    { padding: "8px", }}>
    + style={{ + marginBottom: "4px", + opacity: 0.8, + fontSize: "11px", + textTransform: "uppercase", + }}> Parameters
    - {Object.entries(tool.inputSchema.properties as Record).map( - ([paramName, schema]) => { - const isRequired = - tool.inputSchema && - "required" in tool.inputSchema && - Array.isArray(tool.inputSchema.required) && - tool.inputSchema.required.includes(paramName) + {Object.entries(tool.inputSchema.properties as Record).map(([paramName, schema]) => { + const isRequired = + tool.inputSchema && + "required" in tool.inputSchema && + Array.isArray(tool.inputSchema.required) && + tool.inputSchema.required.includes(paramName) - return ( -
    + - - {paramName} - {isRequired && ( - * - )} - - - {schema.description || "No description"} - -
    - ) - }, - )} + {paramName} + {isRequired && ( + + * + + )} + + + {schema.description || "No description"} + +
    + ) + })}
    )}
    diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index e8c758a333..b8afdbb05f 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -1,10 +1,4 @@ -import { - VSCodeButton, - VSCodeLink, - VSCodePanels, - VSCodePanelTab, - VSCodePanelView, -} from "@vscode/webview-ui-toolkit/react" +import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView } from "@vscode/webview-ui-toolkit/react" import { useState } from "react" import { vscode } from "../../utils/vscode" import { useExtensionState } from "../../context/ExtensionStateContext" @@ -18,6 +12,7 @@ type McpViewProps = { const McpView = ({ onDone }: McpViewProps) => { const { mcpServers: servers } = useExtensionState() + // const [servers, setServers] = useState([ // // Add some mock servers for testing // { @@ -106,35 +101,39 @@ const McpView = ({ onDone }: McpViewProps) => { style={{ color: "var(--vscode-foreground)", fontSize: "13px", - marginBottom: "20px", + marginBottom: "16px", marginTop: "5px", }}> The{" "} Model Context Protocol {" "} - enables communication with locally running MCP servers that provide additional tools and resources - to extend Cline's capabilities. You can use{" "} + enables communication with locally running MCP servers that provide additional tools and resources to extend + Cline's capabilities. You can use{" "} community-made servers {" "} - or ask Cline to create new tools specific to your workflow (e.g., "add a tool that gets the latest - npm docs").{" "} + or ask Cline to create new tools specific to your workflow (e.g., "add a tool that gets the latest npm docs").{" "} See a demo here.
    - {/* Server List */} {servers.length > 0 && ( -
    +
    {servers.map((server) => ( ))}
    )} - {/* Edit Settings Button */} + {/* Server Configuration Button */} +
    { onClick={() => { vscode.postMessage({ type: "openMcpSettings" }) }}> - - Edit MCP Settings + + Configure MCP Servers
    + {/* Advanced Settings Link */} +
    + { + vscode.postMessage({ + type: "openExtensionSettings", + text: "cline.mcp", + }) + }} + style={{ fontSize: "12px" }}> + Advanced MCP Settings + +
    + {/* Bottom padding */}
    @@ -192,15 +205,62 @@ const ServerRow = ({ server }: { server: McpServer }) => { background: "var(--vscode-textCodeBlock-background)", cursor: server.error ? "default" : "pointer", borderRadius: isExpanded || server.error ? "4px 4px 0 0" : "4px", + opacity: server.disabled ? 0.6 : 1, }} onClick={handleRowClick}> {!server.error && ( - + )} {server.name} +
    e.stopPropagation()}> +
    { + vscode.postMessage({ + type: "toggleMcpServer", + serverName: server.name, + disabled: !server.disabled, + }) + }} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault() + vscode.postMessage({ + type: "toggleMcpServer", + serverName: server.name, + disabled: !server.disabled, + }) + } + }}> +
    +
    +
    { appearance="secondary" onClick={handleRestart} disabled={server.status === "connecting"} - style={{ width: "calc(100% - 20px)", margin: "0 10px 10px 10px" }}> + style={{ + width: "calc(100% - 20px)", + margin: "0 10px 10px 10px", + }}> {server.status === "connecting" ? "Retrying..." : "Retry Connection"}
    @@ -250,20 +313,28 @@ const ServerRow = ({ server }: { server: McpServer }) => { Tools ({server.tools?.length || 0}) - Resources ( - {[...(server.resourceTemplates || []), ...(server.resources || [])].length || 0}) + Resources ({[...(server.resourceTemplates || []), ...(server.resources || [])].length || 0}) {server.tools && server.tools.length > 0 ? (
    + style={{ + display: "flex", + flexDirection: "column", + gap: "8px", + width: "100%", + }}> {server.tools.map((tool) => ( - + ))}
    ) : ( -
    +
    No tools found
    )} @@ -273,18 +344,25 @@ const ServerRow = ({ server }: { server: McpServer }) => { {(server.resources && server.resources.length > 0) || (server.resourceTemplates && server.resourceTemplates.length > 0) ? (
    - {[...(server.resourceTemplates || []), ...(server.resources || [])].map( - (item) => ( - - ), - )} + style={{ + display: "flex", + flexDirection: "column", + gap: "8px", + width: "100%", + }}> + {[...(server.resourceTemplates || []), ...(server.resources || [])].map((item) => ( + + ))}
    ) : ( -
    +
    No resources found
    )} @@ -295,7 +373,10 @@ const ServerRow = ({ server }: { server: McpServer }) => { appearance="secondary" onClick={handleRestart} disabled={server.status === "connecting"} - style={{ width: "calc(100% - 14px)", margin: "0 7px 3px 7px" }}> + style={{ + width: "calc(100% - 14px)", + margin: "0 7px 3px 7px", + }}> {server.status === "connecting" ? "Restarting..." : "Restart Server"}
    diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index e77c83b50b..84018b9efd 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -11,14 +11,19 @@ import { Fragment, memo, useCallback, useEffect, useMemo, useState } from "react import { useEvent, useInterval } from "react-use" import { ApiConfiguration, + ApiProvider, ModelInfo, anthropicDefaultModelId, anthropicModels, azureOpenAiDefaultApiVersion, bedrockDefaultModelId, bedrockModels, + deepSeekDefaultModelId, + deepSeekModels, geminiDefaultModelId, geminiModels, + mistralDefaultModelId, + mistralModels, openAiModelInfoSaneDefaults, openAiNativeDefaultModelId, openAiNativeModels, @@ -31,27 +36,55 @@ import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" -import OpenRouterModelPicker, { - ModelDescriptionMarkdown, - OPENROUTER_MODEL_PICKER_Z_INDEX, -} from "./OpenRouterModelPicker" +import OpenRouterModelPicker, { ModelDescriptionMarkdown } from "./OpenRouterModelPicker" +import styled from "styled-components" +import * as vscodemodels from "vscode" interface ApiOptionsProps { showModelOptions: boolean apiErrorMessage?: string modelIdErrorMessage?: string + isPopup?: boolean } -const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) => { +// This is necessary to ensure dropdown opens downward, important for when this is used in popup +const DROPDOWN_Z_INDEX = 1001 // Higher than the OpenRouterModelPicker's and ModelSelectorTooltip's z-index + +const DropdownContainer = styled.div<{ zIndex?: number }>` + position: relative; + z-index: ${(props) => props.zIndex || DROPDOWN_Z_INDEX}; + + // Force dropdowns to open downward + & vscode-dropdown::part(listbox) { + position: absolute !important; + top: 100% !important; + bottom: auto !important; + } +` + +declare module "vscode" { + interface LanguageModelChatSelector { + vendor?: string + family?: string + version?: string + id?: string + } +} + +const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup }: ApiOptionsProps) => { const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) + const [vsCodeLmModels, setVsCodeLmModels] = useState([]) const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => { - setApiConfiguration({ ...apiConfiguration, [field]: event.target.value }) + setApiConfiguration({ + ...apiConfiguration, + [field]: event.target.value, + }) } const { selectedProvider, selectedModelId, selectedModelInfo } = useMemo(() => { @@ -61,17 +94,28 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: // Poll ollama/lmstudio models const requestLocalModels = useCallback(() => { if (selectedProvider === "ollama") { - vscode.postMessage({ type: "requestOllamaModels", text: apiConfiguration?.ollamaBaseUrl }) + vscode.postMessage({ + type: "requestOllamaModels", + text: apiConfiguration?.ollamaBaseUrl, + }) } else if (selectedProvider === "lmstudio") { - vscode.postMessage({ type: "requestLmStudioModels", text: apiConfiguration?.lmStudioBaseUrl }) + vscode.postMessage({ + type: "requestLmStudioModels", + text: apiConfiguration?.lmStudioBaseUrl, + }) + } else if (selectedProvider === "vscode-lm") { + vscode.postMessage({ type: "requestVsCodeLmModels" }) } }, [selectedProvider, apiConfiguration?.ollamaBaseUrl, apiConfiguration?.lmStudioBaseUrl]) useEffect(() => { - if (selectedProvider === "ollama" || selectedProvider === "lmstudio") { + if (selectedProvider === "ollama" || selectedProvider === "lmstudio" || selectedProvider === "vscode-lm") { requestLocalModels() } }, [selectedProvider, requestLocalModels]) - useInterval(requestLocalModels, selectedProvider === "ollama" || selectedProvider === "lmstudio" ? 2000 : null) + useInterval( + requestLocalModels, + selectedProvider === "ollama" || selectedProvider === "lmstudio" || selectedProvider === "vscode-lm" ? 2000 : null, + ) const handleMessage = useCallback((event: MessageEvent) => { const message: ExtensionMessage = event.data @@ -79,6 +123,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: setOllamaModels(message.ollamaModels) } else if (message.type === "lmStudioModels" && message.lmStudioModels) { setLmStudioModels(message.lmStudioModels) + } else if (message.type === "vsCodeLmModels" && message.vsCodeLmModels) { + setVsCodeLmModels(message.vsCodeLmModels) } }, []) useEvent("message", handleMessage) @@ -87,7 +133,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: VSCodeDropdown has an open bug where dynamically rendered options don't auto select the provided value prop. You can see this for yourself by comparing it with normal select/option elements, which work as expected. https://github.com/microsoft/vscode-webview-ui-toolkit/issues/433 - In our case, when the user switches between providers, we recalculate the selectedModelId depending on the provider, the default model for that provider, and a modelId that the user may have selected. Unfortunately, the VSCodeDropdown component wouldn't select this calculated value, and would default to the first "Select a model..." option instead, which makes it seem like the model was cleared out when it wasn't. + In our case, when the user switches between providers, we recalculate the selectedModelId depending on the provider, the default model for that provider, and a modelId that the user may have selected. Unfortunately, the VSCodeDropdown component wouldn't select this calculated value, and would default to the first "Select a model..." option instead, which makes it seem like the model was cleared out when it wasn't. As a workaround, we create separate instances of the dropdown for each provider, and then conditionally render the one that matches the current provider. */ @@ -116,8 +162,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: } return ( -
    -
    +
    + @@ -125,18 +171,25 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: id="api-provider" value={selectedProvider} onChange={handleInputChange("apiProvider")} - style={{ minWidth: 130, position: "relative", zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX + 1 }}> + style={{ + minWidth: 130, + position: "relative", + }}> OpenRouter Anthropic Google Gemini + DeepSeek + Mistral GCP Vertex AI AWS Bedrock OpenAI OpenAI Compatible + VS Code LM API LM Studio Ollama + LiteLLM -
    + {selectedProvider === "anthropic" && (
    @@ -155,7 +208,10 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: const isChecked = e.target.checked === true setAnthropicBaseUrlSelected(isChecked) if (!isChecked) { - setApiConfiguration({ ...apiConfiguration, anthropicBaseUrl: "" }) + setApiConfiguration({ + ...apiConfiguration, + anthropicBaseUrl: "", + }) } }}> Use custom base URL @@ -181,7 +237,10 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: {!apiConfiguration?.apiKey && ( + style={{ + display: "inline", + fontSize: "inherit", + }}> You can get an Anthropic API key by signing up here. )} @@ -209,7 +268,10 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: {!apiConfiguration?.openAiNativeApiKey && ( + style={{ + display: "inline", + fontSize: "inherit", + }}> You can get an OpenAI API key by signing up here. )} @@ -217,6 +279,68 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }:
    )} + {selectedProvider === "deepseek" && ( +
    + + DeepSeek API Key + +

    + This key is stored locally and only used to make API requests from this extension. + {!apiConfiguration?.deepSeekApiKey && ( + + You can get a DeepSeek API key by signing up here. + + )} +

    +
    + )} + + {selectedProvider === "mistral" && ( +
    + + Mistral API Key + +

    + This key is stored locally and only used to make API requests from this extension. + {!apiConfiguration?.mistralApiKey && ( + + You can get a Mistral API key by signing up here. + + )} +

    +
    + )} + {selectedProvider === "openrouter" && (
    +
    AWS Session Token -
    + @@ -314,12 +443,15 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: us-gov-west-1 {/* us-gov-east-1 */} -
    + { const isChecked = e.target.checked === true - setApiConfiguration({ ...apiConfiguration, awsUseCrossRegionInference: isChecked }) + setApiConfiguration({ + ...apiConfiguration, + awsUseCrossRegionInference: isChecked, + }) }}> Use cross-region inference @@ -329,15 +461,20 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - Authenticate by either providing the keys above or use the default AWS credential providers, - i.e. ~/.aws/credentials or environment variables. These credentials are only used locally to - make API requests from this extension. + Authenticate by either providing the keys above or use the default AWS credential providers, i.e. + ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests + from this extension.

    )} {apiConfiguration?.apiProvider === "vertex" && ( -
    +
    Google Cloud Project ID -
    + @@ -361,7 +498,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: europe-west4 asia-southeast1 -
    +

    - { - "1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models," - } + {"1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,"} {" "} + style={{ + display: "inline", + fontSize: "inherit", + }}> You can get a Gemini API key by signing up here. )} @@ -444,7 +582,10 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: const isChecked = e.target.checked === true setAzureApiVersionSelected(isChecked) if (!isChecked) { - setApiConfiguration({ ...apiConfiguration, azureApiVersion: "" }) + setApiConfiguration({ + ...apiConfiguration, + azureApiVersion: "", + }) } }}> Set Azure API version @@ -464,13 +605,75 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: color: "var(--vscode-descriptionForeground)", }}> - (Note: Cline uses complex prompts and works best - with Claude models. Less capable models may not work as expected.) + (Note: Cline uses complex prompts and works best with Claude + models. Less capable models may not work as expected.)

    )} + {selectedProvider === "vscode-lm" && ( +
    + + + {vsCodeLmModels.length > 0 ? ( + { + const value = (e.target as HTMLInputElement).value + if (!value) { + return + } + const [vendor, family] = value.split("/") + handleInputChange("vsCodeLmModelSelector")({ + target: { + value: { vendor, family }, + }, + }) + }} + style={{ width: "100%" }}> + Select a model... + {vsCodeLmModels.map((model) => ( + + {model.vendor} - {model.family} + + ))} + + ) : ( +

    + The VS Code Language Model API allows you to run models provided by other VS Code extensions + (including but not limited to GitHub Copilot). The easiest way to get started is to install the + Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet. +

    + )} + +

    + Note: This is a very experimental integration and may not work as expected. +

    +
    +
    + )} + {selectedProvider === "lmstudio" && (
    {lmStudioModels.map((model) => ( - + {model} ))} @@ -520,8 +720,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - LM Studio allows you to run models locally on your computer. For instructions on how to get - started, see their + LM Studio allows you to run models locally on your computer. For instructions on how to get started, see + their quickstart guide. @@ -533,13 +733,45 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: {" "} feature to use it with this extension.{" "} - (Note: Cline uses complex prompts and works best - with Claude models. Less capable models may not work as expected.) + (Note: Cline uses complex prompts and works best with Claude + models. Less capable models may not work as expected.)

    )} + {selectedProvider === "litellm" && ( +
    + + Base URL (optional) + + + Model ID + +

    + LiteLLM provides a unified interface to access various LLM providers' models. See their{" "} + + quickstart guide + {" "} + for more information. +

    +
    + )} + {selectedProvider === "ollama" && (
    {ollamaModels.map((model) => ( - + {model} ))} @@ -589,16 +818,16 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - Ollama allows you to run models locally on your computer. For instructions on how to get - started, see their + Ollama allows you to run models locally on your computer. For instructions on how to get started, see + their quickstart guide. - (Note: Cline uses complex prompts and works best - with Claude models. Less capable models may not work as expected.) + (Note: Cline uses complex prompts and works best with Claude + models. Less capable models may not work as expected.)

    @@ -615,15 +844,14 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }:

    )} - {selectedProvider === "openrouter" && showModelOptions && } - {selectedProvider !== "openrouter" && selectedProvider !== "openai" && selectedProvider !== "ollama" && selectedProvider !== "lmstudio" && + selectedProvider !== "vscode-lm" && showModelOptions && ( <> -
    + @@ -632,17 +860,22 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: {selectedProvider === "vertex" && createDropdown(vertexModels)} {selectedProvider === "gemini" && createDropdown(geminiModels)} {selectedProvider === "openai-native" && createDropdown(openAiNativeModels)} -
    + {selectedProvider === "deepseek" && createDropdown(deepSeekModels)} + {selectedProvider === "mistral" && createDropdown(mistralModels)} + )} + {selectedProvider === "openrouter" && showModelOptions && } + {modelIdErrorMessage && (

    void + isPopup?: boolean }) => { const isGemini = Object.keys(geminiModels).includes(selectedModelId) @@ -690,6 +925,7 @@ export const ModelInfoView = ({ markdown={modelInfo.description} isExpanded={isDescriptionExpanded} setIsExpanded={setIsDescriptionExpanded} + isPopup={isPopup} /> ), - Cache writes price:{" "} - {formatPrice(modelInfo.cacheWritesPrice || 0)}/million tokens + Cache writes price: {formatPrice(modelInfo.cacheWritesPrice || 0)} + /million tokens ), modelInfo.supportsPromptCache && modelInfo.cacheReadsPrice && ( - Cache reads price:{" "} - {formatPrice(modelInfo.cacheReadsPrice || 0)}/million tokens + Cache reads price: {formatPrice(modelInfo.cacheReadsPrice || 0)}/million + tokens ), modelInfo.outputPrice !== undefined && modelInfo.outputPrice > 0 && ( - Output price: {formatPrice(modelInfo.outputPrice)}/million - tokens + Output price: {formatPrice(modelInfo.outputPrice)}/million tokens ), isGemini && ( - * Free up to {selectedModelId && selectedModelId.includes("flash") ? "15" : "2"} requests per minute. - After that, billing depends on prompt size.{" "} + * Free up to {selectedModelId && selectedModelId.includes("flash") ? "15" : "2"} requests per minute. After that, + billing depends on prompt size.{" "} For more info, see pricing details. @@ -752,7 +987,12 @@ export const ModelInfoView = ({ ].filter(Boolean) return ( -

    +

    {infoItems.map((item, index) => ( {item} @@ -791,7 +1031,11 @@ const ModelInfoSupportsItem = ({ ) -export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { +export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): { + selectedProvider: ApiProvider + selectedModelId: string + selectedModelInfo: ModelInfo +} { const provider = apiConfiguration?.apiProvider || "anthropic" const modelId = apiConfiguration?.apiModelId @@ -805,7 +1049,11 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { selectedModelId = defaultId selectedModelInfo = models[defaultId] } - return { selectedProvider: provider, selectedModelId, selectedModelInfo } + return { + selectedProvider: provider, + selectedModelId, + selectedModelInfo, + } } switch (provider) { case "anthropic": @@ -818,6 +1066,10 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { return getProviderData(geminiModels, geminiDefaultModelId) case "openai-native": return getProviderData(openAiNativeModels, openAiNativeDefaultModelId) + case "deepseek": + return getProviderData(deepSeekModels, deepSeekDefaultModelId) + case "mistral": + return getProviderData(mistralModels, mistralDefaultModelId) case "openrouter": return { selectedProvider: provider, @@ -842,6 +1094,23 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { selectedModelId: apiConfiguration?.lmStudioModelId || "", selectedModelInfo: openAiModelInfoSaneDefaults, } + case "vscode-lm": + return { + selectedProvider: provider, + selectedModelId: apiConfiguration?.vsCodeLmModelSelector + ? `${apiConfiguration.vsCodeLmModelSelector.vendor}/${apiConfiguration.vsCodeLmModelSelector.family}` + : "", + selectedModelInfo: { + ...openAiModelInfoSaneDefaults, + supportsImages: false, // VSCode LM API currently doesn't support images + }, + } + case "litellm": + return { + selectedProvider: provider, + selectedModelId: apiConfiguration?.liteLlmModelId || "", + selectedModelInfo: openAiModelInfoSaneDefaults, + } default: return getProviderData(anthropicModels, anthropicDefaultModelId) } diff --git a/webview-ui/src/components/settings/OpenAiModelPicker.tsx b/webview-ui/src/components/settings/OpenAiModelPicker.tsx new file mode 100644 index 0000000000..82bac0b7b4 --- /dev/null +++ b/webview-ui/src/components/settings/OpenAiModelPicker.tsx @@ -0,0 +1,360 @@ +import { VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" +import Fuse from "fuse.js" +import React, { KeyboardEvent, memo, useEffect, useMemo, useRef, useState } from "react" +import { useRemark } from "react-remark" +import styled from "styled-components" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { vscode } from "../../utils/vscode" +import { highlight } from "../history/HistoryView" + +const OpenAiModelPicker: React.FC = () => { + const { apiConfiguration, setApiConfiguration, openAiModels } = useExtensionState() + const [searchTerm, setSearchTerm] = useState(apiConfiguration?.openAiModelId || "") + const [isDropdownVisible, setIsDropdownVisible] = useState(false) + const [selectedIndex, setSelectedIndex] = useState(-1) + const dropdownRef = useRef(null) + const itemRefs = useRef<(HTMLDivElement | null)[]>([]) + const dropdownListRef = useRef(null) + + const handleModelChange = (newModelId: string) => { + // could be setting invalid model id/undefined info but validation will catch it + setApiConfiguration({ + ...apiConfiguration, + openAiModelId: newModelId, + }) + setSearchTerm(newModelId) + } + + useEffect(() => { + vscode.postMessage({ type: "refreshOpenAiModels" }) + }, [apiConfiguration?.openAiBaseUrl, apiConfiguration?.openAiApiKey]) + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsDropdownVisible(false) + } + } + + document.addEventListener("mousedown", handleClickOutside) + return () => { + document.removeEventListener("mousedown", handleClickOutside) + } + }, []) + + const modelIds = useMemo(() => { + return openAiModels.sort((a, b) => a.localeCompare(b)) + }, [openAiModels]) + + const searchableItems = useMemo(() => { + return modelIds.map((id) => ({ + id, + html: id, + })) + }, [modelIds]) + + const fuse = useMemo(() => { + return new Fuse(searchableItems, { + keys: ["html"], // highlight function will update this + threshold: 0.6, + shouldSort: true, + isCaseSensitive: false, + ignoreLocation: false, + includeMatches: true, + minMatchCharLength: 1, + }) + }, [searchableItems]) + + const modelSearchResults = useMemo(() => { + let results: { id: string; html: string }[] = searchTerm + ? highlight(fuse.search(searchTerm), "model-item-highlight") + : searchableItems + // results.sort((a, b) => a.id.localeCompare(b.id)) NOTE: sorting like this causes ids in objects to be reordered and mismatched + return results + }, [searchableItems, searchTerm, fuse]) + + const handleKeyDown = (event: KeyboardEvent) => { + if (!isDropdownVisible) return + + switch (event.key) { + case "ArrowDown": + event.preventDefault() + setSelectedIndex((prev) => (prev < modelSearchResults.length - 1 ? prev + 1 : prev)) + break + case "ArrowUp": + event.preventDefault() + setSelectedIndex((prev) => (prev > 0 ? prev - 1 : prev)) + break + case "Enter": + event.preventDefault() + if (selectedIndex >= 0 && selectedIndex < modelSearchResults.length) { + handleModelChange(modelSearchResults[selectedIndex].id) + setIsDropdownVisible(false) + } + break + case "Escape": + setIsDropdownVisible(false) + setSelectedIndex(-1) + break + } + } + + useEffect(() => { + setSelectedIndex(-1) + if (dropdownListRef.current) { + dropdownListRef.current.scrollTop = 0 + } + }, [searchTerm]) + + useEffect(() => { + if (selectedIndex >= 0 && itemRefs.current[selectedIndex]) { + itemRefs.current[selectedIndex]?.scrollIntoView({ + block: "nearest", + behavior: "smooth", + }) + } + }, [selectedIndex]) + + return ( + <> + +

    + + { + handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase()) + setIsDropdownVisible(true) + }} + onFocus={() => setIsDropdownVisible(true)} + onKeyDown={handleKeyDown} + style={{ width: "100%", zIndex: OPENAI_MODEL_PICKER_Z_INDEX, position: "relative" }}> + {searchTerm && ( +
    { + handleModelChange("") + setIsDropdownVisible(true) + }} + slot="end" + style={{ + display: "flex", + justifyContent: "center", + alignItems: "center", + height: "100%", + }} + /> + )} + + {isDropdownVisible && ( + + {modelSearchResults.map((item, index) => ( + (itemRefs.current[index] = el)} + isSelected={index === selectedIndex} + onMouseEnter={() => setSelectedIndex(index)} + onClick={() => { + handleModelChange(item.id) + setIsDropdownVisible(false) + }} + dangerouslySetInnerHTML={{ + __html: item.html, + }} + /> + ))} + + )} + +
    + + ) +} + +export default OpenAiModelPicker + +// Dropdown + +const DropdownWrapper = styled.div` + position: relative; + width: 100%; +` + +export const OPENAI_MODEL_PICKER_Z_INDEX = 1_000 + +const DropdownList = styled.div` + position: absolute; + top: calc(100% - 3px); + left: 0; + width: calc(100% - 2px); + max-height: 200px; + overflow-y: auto; + background-color: var(--vscode-dropdown-background); + border: 1px solid var(--vscode-list-activeSelectionBackground); + z-index: ${OPENAI_MODEL_PICKER_Z_INDEX - 1}; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +` + +const DropdownItem = styled.div<{ isSelected: boolean }>` + padding: 5px 10px; + cursor: pointer; + word-break: break-all; + white-space: normal; + + background-color: ${({ isSelected }) => (isSelected ? "var(--vscode-list-activeSelectionBackground)" : "inherit")}; + + &:hover { + background-color: var(--vscode-list-activeSelectionBackground); + } +` + +// Markdown + +const StyledMarkdown = styled.div` + font-family: + var(--vscode-font-family), + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; + font-size: 12px; + color: var(--vscode-descriptionForeground); + + p, + li, + ol, + ul { + line-height: 1.25; + margin: 0; + } + + ol, + ul { + padding-left: 1.5em; + margin-left: 0; + } + + p { + white-space: pre-wrap; + } + + a { + text-decoration: none; + } + a { + &:hover { + text-decoration: underline; + } + } +` + +export const ModelDescriptionMarkdown = memo( + ({ + markdown, + key, + isExpanded, + setIsExpanded, + }: { + markdown?: string + key: string + isExpanded: boolean + setIsExpanded: (isExpanded: boolean) => void + }) => { + const [reactContent, setMarkdown] = useRemark() + // const [isExpanded, setIsExpanded] = useState(false) + const [showSeeMore, setShowSeeMore] = useState(false) + const textContainerRef = useRef(null) + const textRef = useRef(null) + + useEffect(() => { + setMarkdown(markdown || "") + }, [markdown, setMarkdown]) + + useEffect(() => { + if (textRef.current && textContainerRef.current) { + const { scrollHeight } = textRef.current + const { clientHeight } = textContainerRef.current + const isOverflowing = scrollHeight > clientHeight + setShowSeeMore(isOverflowing) + // if (!isOverflowing) { + // setIsExpanded(false) + // } + } + }, [reactContent, setIsExpanded]) + + return ( + +
    +
    + {reactContent} +
    + {!isExpanded && showSeeMore && ( +
    +
    + setIsExpanded(true)}> + See more + +
    + )} +
    + + ) + }, +) diff --git a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx index bd4efd8bc1..37b0bbfad3 100644 --- a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx +++ b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx @@ -9,8 +9,13 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { highlight } from "../history/HistoryView" import { ModelInfoView, normalizeApiConfiguration } from "./ApiOptions" +import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" -const OpenRouterModelPicker: React.FC = () => { +export interface OpenRouterModelPickerProps { + isPopup?: boolean +} + +const OpenRouterModelPicker: React.FC = ({ isPopup }) => { const { apiConfiguration, setApiConfiguration, openRouterModels } = useExtensionState() const [searchTerm, setSearchTerm] = useState(apiConfiguration?.openRouterModelId || openRouterDefaultModelId) const [isDropdownVisible, setIsDropdownVisible] = useState(false) @@ -24,8 +29,10 @@ const OpenRouterModelPicker: React.FC = () => { // could be setting invalid model id/undefined info but validation will catch it setApiConfiguration({ ...apiConfiguration, - openRouterModelId: newModelId, - openRouterModelInfo: openRouterModels[newModelId], + ...{ + openRouterModelId: newModelId, + openRouterModelInfo: openRouterModels[newModelId], + }, }) setSearchTerm(newModelId) } @@ -129,7 +136,7 @@ const OpenRouterModelPicker: React.FC = () => { }, [selectedIndex]) return ( - <> +
    -
    +
    @@ -153,7 +160,11 @@ const OpenRouterModelPicker: React.FC = () => { }} onFocus={() => setIsDropdownVisible(true)} onKeyDown={handleKeyDown} - style={{ width: "100%", zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX, position: "relative" }}> + style={{ + width: "100%", + zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX, + position: "relative", + }}> {searchTerm && (
    { modelInfo={selectedModelInfo} isDescriptionExpanded={isDescriptionExpanded} setIsDescriptionExpanded={setIsDescriptionExpanded} + isPopup={isPopup} /> ) : (

    { marginTop: 0, color: "var(--vscode-descriptionForeground)", }}> - The extension automatically fetches the latest list of models available on{" "} - - OpenRouter. - - If you're unsure which model to choose, Cline works best with{" "} - handleModelChange("anthropic/claude-3.5-sonnet:beta")}> - anthropic/claude-3.5-sonnet:beta. - - You can also try searching "free" for no-cost options currently available. + <> + The extension automatically fetches the latest list of models available on{" "} + + OpenRouter. + + If you're unsure which model to choose, Cline works best with{" "} + handleModelChange("anthropic/claude-3.5-sonnet:beta")}> + anthropic/claude-3.5-sonnet:beta. + + You can also try searching "free" for no-cost options currently available. +

    )} - +
    ) } @@ -316,11 +330,13 @@ export const ModelDescriptionMarkdown = memo( key, isExpanded, setIsExpanded, + isPopup, }: { markdown?: string key: string isExpanded: boolean setIsExpanded: (isExpanded: boolean) => void + isPopup?: boolean }) => { const [reactContent, setMarkdown] = useRemark() // const [isExpanded, setIsExpanded] = useState(false) @@ -380,8 +396,7 @@ export const ModelDescriptionMarkdown = memo( style={{ width: 30, height: "1.2em", - background: - "linear-gradient(to right, transparent, var(--vscode-sideBar-background))", + background: "linear-gradient(to right, transparent, var(--vscode-sideBar-background))", }} /> setIsExpanded(true)}> See more diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index bed3913a27..ad1e141fa5 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -4,7 +4,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" - +import SettingsButton from "../common/SettingsButton" const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { @@ -12,19 +12,23 @@ type SettingsViewProps = { } const SettingsView = ({ onDone }: SettingsViewProps) => { - const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = - useExtensionState() + const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) + const handleSubmit = () => { const apiValidationResult = validateApiConfiguration(apiConfiguration) const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) setApiErrorMessage(apiValidationResult) setModelIdErrorMessage(modelIdValidationResult) + if (!apiValidationResult && !modelIdValidationResult) { vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) - vscode.postMessage({ type: "customInstructions", text: customInstructions }) + vscode.postMessage({ + type: "customInstructions", + text: customInstructions, + }) onDone() } } @@ -75,7 +79,13 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { Done
    + style={{ + flexGrow: 1, + overflowY: "scroll", + paddingRight: 8, + display: "flex", + flexDirection: "column", + }}>
    { setCustomInstructions(e.target?.value ?? "")}> Custom Instructions @@ -122,22 +131,49 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { )} +
    + vscode.postMessage({ type: "openExtensionSettings" })} + style={{ + margin: "0 0 16px 0", + }}> + + Advanced Settings + +
    -

    +

    If you have any questions or feedback, feel free to open an issue at{" "} https://github.com/cline/cline

    -

    v{version}

    +

    + v{version} +

    diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index ef15a4ed50..330870f56a 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -1,14 +1,18 @@ -import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" -import { useEffect, useState } from "react" +import { VSCodeButton, VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" +import { useEffect, useState, useCallback } from "react" import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "../settings/ApiOptions" +import { useEvent } from "react-use" +import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" const WelcomeView = () => { const { apiConfiguration } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) + const [email, setEmail] = useState("") + const [isSubscribed, setIsSubscribed] = useState(false) const disableLetsGoButton = apiErrorMessage != null @@ -16,32 +20,98 @@ const WelcomeView = () => { vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) } + const handleSubscribe = () => { + if (email) { + vscode.postMessage({ type: "subscribeEmail", text: email }) + } + } + useEffect(() => { setApiErrorMessage(validateApiConfiguration(apiConfiguration)) }, [apiConfiguration]) + // Add message handler for subscription confirmation + const handleMessage = useCallback((e: MessageEvent) => { + const message: ExtensionMessage = e.data + if (message.type === "emailSubscribed") { + setIsSubscribed(true) + setEmail("") + } + }, []) + + useEvent("message", handleMessage) + return ( -
    -

    Hi, I'm Cline

    -

    - I can do all kinds of tasks thanks to the latest breakthroughs in{" "} - - Claude 3.5 Sonnet's agentic coding capabilities - {" "} - and access to tools that let me create & edit files, explore complex projects, use the browser, and - execute terminal commands (with your permission, of course). I can even use MCP to create new tools and - extend my own capabilities. -

    +
    +
    +

    Hi, I'm Cline

    +

    + I can do all kinds of tasks thanks to the latest breakthroughs in{" "} + + Claude 3.5 Sonnet's agentic coding capabilities + {" "} + and access to tools that let me create & edit files, explore complex projects, use the browser, and execute + terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own + capabilities. +

    - To get started, this extension needs an API provider for Claude 3.5 Sonnet. + To get started, this extension needs an API provider for Claude 3.5 Sonnet. -
    - - - Let's go! - +
    + {isSubscribed ? ( +

    + + Thanks for subscribing! We'll keep you updated on new features. +

    + ) : ( + <> +

    + While Cline currently requires you bring your own API key, we are working on an official accounts + system with additional capabilities. Subscribe to our mailing list to get updates! +

    +
    + setEmail(e.target.value)} + placeholder="Enter your email" + style={{ flex: 1 }} + /> + + Subscribe + +
    + + )} +
    + +
    + + + Let's go! + +
    ) diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 22e862e0fc..626e9e6606 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -2,22 +2,20 @@ import React, { createContext, useCallback, useContext, useEffect, useState } fr import { useEvent } from "react-use" import { DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../../src/shared/AutoApprovalSettings" import { ExtensionMessage, ExtensionState } from "../../../src/shared/ExtensionMessage" -import { - ApiConfiguration, - ModelInfo, - openRouterDefaultModelId, - openRouterDefaultModelInfo, -} from "../../../src/shared/api" +import { ApiConfiguration, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../../src/shared/api" import { findLastIndex } from "../../../src/shared/array" import { McpServer } from "../../../src/shared/mcp" import { convertTextMateToHljs } from "../utils/textMateToHljs" import { vscode } from "../utils/vscode" +import { DEFAULT_BROWSER_SETTINGS } from "../../../src/shared/BrowserSettings" +import { DEFAULT_CHAT_SETTINGS } from "../../../src/shared/ChatSettings" interface ExtensionStateContextType extends ExtensionState { didHydrateState: boolean showWelcome: boolean theme: any openRouterModels: Record + openAiModels: string[] mcpServers: McpServer[] filePaths: string[] setApiConfiguration: (config: ApiConfiguration) => void @@ -27,13 +25,18 @@ interface ExtensionStateContextType extends ExtensionState { const ExtensionStateContext = createContext(undefined) -export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { +export const ExtensionStateContextProvider: React.FC<{ + children: React.ReactNode +}> = ({ children }) => { const [state, setState] = useState({ version: "", clineMessages: [], taskHistory: [], shouldShowAnnouncement: false, autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, + browserSettings: DEFAULT_BROWSER_SETTINGS, + chatSettings: DEFAULT_CHAT_SETTINGS, + isLoggedIn: false, }) const [didHydrateState, setDidHydrateState] = useState(false) const [showWelcome, setShowWelcome] = useState(false) @@ -42,6 +45,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode const [openRouterModels, setOpenRouterModels] = useState>({ [openRouterDefaultModelId]: openRouterDefaultModelInfo, }) + + const [openAiModels, setOpenAiModels] = useState([]) const [mcpServers, setMcpServers] = useState([]) const handleMessage = useCallback((event: MessageEvent) => { @@ -61,6 +66,9 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode config.lmStudioModelId, config.geminiApiKey, config.openAiNativeApiKey, + config.deepSeekApiKey, + config.mistralApiKey, + config.vsCodeLmModelSelector, ].some((key) => key !== undefined) : false setShowWelcome(!hasKey) @@ -99,6 +107,11 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode }) break } + case "openAiModels": { + const updatedModels = message.openAiModels ?? [] + setOpenAiModels(updatedModels) + break + } case "mcpServers": { setMcpServers(message.mcpServers ?? []) break @@ -118,11 +131,24 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode showWelcome, theme, openRouterModels, + openAiModels, mcpServers, filePaths, - setApiConfiguration: (value) => setState((prevState) => ({ ...prevState, apiConfiguration: value })), - setCustomInstructions: (value) => setState((prevState) => ({ ...prevState, customInstructions: value })), - setShowAnnouncement: (value) => setState((prevState) => ({ ...prevState, shouldShowAnnouncement: value })), + setApiConfiguration: (value) => + setState((prevState) => ({ + ...prevState, + apiConfiguration: value, + })), + setCustomInstructions: (value) => + setState((prevState) => ({ + ...prevState, + customInstructions: value, + })), + setShowAnnouncement: (value) => + setState((prevState) => ({ + ...prevState, + shouldShowAnnouncement: value, + })), } return {children} diff --git a/webview-ui/src/utils/context-mentions.ts b/webview-ui/src/utils/context-mentions.ts index a79aefb3da..07b5ce5e75 100644 --- a/webview-ui/src/utils/context-mentions.ts +++ b/webview-ui/src/utils/context-mentions.ts @@ -1,10 +1,6 @@ import { mentionRegex } from "../../../src/shared/context-mentions" -export function insertMention( - text: string, - position: number, - value: string, -): { newValue: string; mentionIndex: number } { +export function insertMention(text: string, position: number, value: string): { newValue: string; mentionIndex: number } { const beforeCursor = text.slice(0, position) const afterCursor = text.slice(position) @@ -68,14 +64,20 @@ export function getContextMenuOptions( if (selectedType === ContextMenuOptionType.File) { const files = queryItems .filter((item) => item.type === ContextMenuOptionType.File) - .map((item) => ({ type: ContextMenuOptionType.File, value: item.value })) + .map((item) => ({ + type: ContextMenuOptionType.File, + value: item.value, + })) return files.length > 0 ? files : [{ type: ContextMenuOptionType.NoResults }] } if (selectedType === ContextMenuOptionType.Folder) { const folders = queryItems .filter((item) => item.type === ContextMenuOptionType.Folder) - .map((item) => ({ type: ContextMenuOptionType.Folder, value: item.value })) + .map((item) => ({ + type: ContextMenuOptionType.Folder, + value: item.value, + })) return folders.length > 0 ? folders : [{ type: ContextMenuOptionType.NoResults }] } diff --git a/webview-ui/src/utils/mcp.ts b/webview-ui/src/utils/mcp.ts index 5df5df3a61..e7a17b5bcd 100644 --- a/webview-ui/src/utils/mcp.ts +++ b/webview-ui/src/utils/mcp.ts @@ -6,10 +6,7 @@ import { McpResource, McpResourceTemplate } from "../../../src/shared/mcp" * @param templates Array of URI templates to match against * @returns The matching template or undefined if no match is found */ -export function findMatchingTemplate( - uri: string, - templates: McpResourceTemplate[] = [], -): McpResourceTemplate | undefined { +export function findMatchingTemplate(uri: string, templates: McpResourceTemplate[] = []): McpResourceTemplate | undefined { return templates.find((template) => { // Convert template to regex pattern const pattern = String(template.uriTemplate) diff --git a/webview-ui/src/utils/size.ts b/webview-ui/src/utils/size.ts new file mode 100644 index 0000000000..e6b2bd3fe0 --- /dev/null +++ b/webview-ui/src/utils/size.ts @@ -0,0 +1,9 @@ +import prettyBytes from "pretty-bytes" + +export function formatSize(bytes?: number) { + if (bytes === undefined) { + return "--kb" + } + + return prettyBytes(bytes) +} diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 437e1267f3..beafc65572 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -33,12 +33,18 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s return "You must provide a valid API key or choose a different provider." } break + case "deepseek": + if (!apiConfiguration.deepSeekApiKey) { + return "You must provide a valid API key or choose a different provider." + } + break + case "mistral": + if (!apiConfiguration.mistralApiKey) { + return "You must provide a valid API key or choose a different provider." + } + break case "openai": - if ( - !apiConfiguration.openAiBaseUrl || - !apiConfiguration.openAiApiKey || - !apiConfiguration.openAiModelId - ) { + if (!apiConfiguration.openAiBaseUrl || !apiConfiguration.openAiApiKey || !apiConfiguration.openAiModelId) { return "You must provide a valid base URL, API key, and model ID." } break @@ -52,6 +58,11 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s return "You must provide a valid model ID." } break + case "vscode-lm": + if (!apiConfiguration.vsCodeLmModelSelector) { + return "You must provide a valid model selector." + } + break } } return undefined diff --git a/webview-ui/src/utils/vscStyles.ts b/webview-ui/src/utils/vscStyles.ts new file mode 100644 index 0000000000..69faa5fbad --- /dev/null +++ b/webview-ui/src/utils/vscStyles.ts @@ -0,0 +1,41 @@ +export const VSC_INPUT_BACKGROUND = "--vscode-input-background" +export const VSC_SIDEBAR_BACKGROUND = "--vscode-sideBar-background" +export const VSC_FOREGROUND = "--vscode-foreground" +export const VSC_EDITOR_FOREGROUND = "--vscode-editor-foreground" +export const VSC_FOREGROUND_MUTED = "--vscode-foreground-muted" +export const VSC_DESCRIPTION_FOREGROUND = "--vscode-descriptionForeground" +export const VSC_INPUT_PLACEHOLDER_FOREGROUND = "--vscode-input-placeholderForeground" +export const VSC_BUTTON_BACKGROUND = "--vscode-button-background" +export const VSC_BUTTON_FOREGROUND = "--vscode-button-foreground" +export const VSC_EDITOR_BACKGROUND = "--vscode-editor-background" +export const VSC_LIST_SELECTION_BACKGROUND = "--vscode-list-activeSelectionBackground" +export const VSC_FOCUS_BORDER = "--vscode-focus-border" +export const VSC_LIST_ACTIVE_FOREGROUND = "--vscode-quickInputList-focusForeground" +export const VSC_QUICK_INPUT_BACKGROUND = "--vscode-quickInput-background" +export const VSC_INPUT_BORDER = "--vscode-input-border" +export const VSC_INPUT_BORDER_FOCUS = "--vscode-focusBorder" +export const VSC_BADGE_BACKGROUND = "--vscode-badge-background" +export const VSC_BADGE_FOREGROUND = "--vscode-badge-foreground" +export const VSC_SIDEBAR_BORDER = "--vscode-sideBar-border" +export const VSC_DIFF_REMOVED_LINE_BACKGROUND = "--vscode-diffEditor-removedLineBackground" +export const VSC_DIFF_INSERTED_LINE_BACKGROUND = "--vscode-diffEditor-insertedLineBackground" +export const VSC_INACTIVE_SELECTION_BACKGROUND = "--vscode-editor-inactiveSelectionBackground" +export const VSC_TITLEBAR_INACTIVE_FOREGROUND = "--vscode-titleBar-inactiveForeground" + +export function getAsVar(varName: string): string { + return `var(${varName})` +} + +export function hexToRGB(hexColor: string): { r: number; g: number; b: number } { + const hex = hexColor.replace(/^#/, "").slice(0, 6) + const [r, g, b] = [0, 2, 4].map((offset) => parseInt(hex.slice(offset, offset + 2), 16)) + return { r, g, b } +} + +export function colorToHex(colorVar: string): string { + const value = getComputedStyle(document.documentElement).getPropertyValue(colorVar).trim() + if (value.startsWith("#")) return value.slice(0, 7) + + const rgbValues = value.match(/\d+/g)?.slice(0, 3).map(Number) || [] + return `#${rgbValues.map((x) => x.toString(16).padStart(2, "0")).join("")}` +} diff --git a/webview-ui/tsconfig.json b/webview-ui/tsconfig.json index 8a9f459684..3552b166de 100644 --- a/webview-ui/tsconfig.json +++ b/webview-ui/tsconfig.json @@ -16,5 +16,6 @@ "noEmit": true, "jsx": "react-jsx" }, - "include": ["src", "../src/shared"] + "include": ["src", "../src/shared"], + "exclude": ["src/**/*.spec.ts", "setupTests.js", "matchMedia.js"] } diff --git a/webview-ui/vite.config.js b/webview-ui/vite.config.js new file mode 100644 index 0000000000..04c560aa10 --- /dev/null +++ b/webview-ui/vite.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config" + +export default defineConfig({ + test: { + environment: "jsdom", + globals: true, + setupFiles: ["./setupTests.js"], + }, +})