diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aa2b82a6..88113b84 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "C/ua - OSS", + "name": "Cua - OSS", "build": { "dockerfile": "../Dockerfile" }, @@ -10,7 +10,7 @@ "forwardPorts": [7860], "portsAttributes": { "7860": { - "label": "C/ua web client (Gradio)", + "label": "Cua web client (Gradio)", "onAutoForward": "silent" } }, diff --git a/.vscode/docs.code-workspace b/.vscode/docs.code-workspace new file mode 100644 index 00000000..1e1153b6 --- /dev/null +++ b/.vscode/docs.code-workspace @@ -0,0 +1,16 @@ +{ + "folders": [ + { + "path": "../docs" + } + ], + "settings": { + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true + } + } +} \ No newline at end of file diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md deleted file mode 100644 index a1390381..00000000 --- a/COMPATIBILITY.md +++ /dev/null @@ -1,86 +0,0 @@ -# C/ua Compatibility Matrix - -## Table of Contents -- [Host OS Compatibility](#host-os-compatibility) - - [macOS Host](#macos-host) - - [Ubuntu/Linux Host](#ubuntulinux-host) - - [Windows Host](#windows-host) -- [VM Emulation Support](#vm-emulation-support) -- [Model Provider Compatibility](#model-provider-compatibility) - ---- - -## Host OS Compatibility - -*This section shows compatibility based on your **host operating system** (the OS you're running C/ua on).* - -### macOS Host - -| Installation Method | Requirements | Lume | Cloud | Notes | -|-------------------|-------------|------|-------|-------| -| **playground-docker.sh** | Docker Desktop | ✅ Full | ✅ Full | Recommended for quick setup | -| **Dev Container** | VS Code/WindSurf + Docker | ✅ Full | ✅ Full | Best for development | -| **PyPI packages** | Python 3.12+ | ✅ Full | ✅ Full | Most flexible | - -**macOS Host Requirements:** -- macOS 15+ (Sequoia) for local VM support -- Apple Silicon (M1/M2/M3/M4) recommended for best performance -- Docker Desktop for containerized installations - ---- - -### Ubuntu/Linux Host - -| Installation Method | Requirements | Lume | Cloud | Notes | -|-------------------|-------------|------|-------|-------| -| **playground-docker.sh** | Docker Engine | ✅ Full | ✅ Full | Recommended for quick setup | -| **Dev Container** | VS Code/WindSurf + Docker | ✅ Full | ✅ Full | Best for development | -| **PyPI packages** | Python 3.12+ | ✅ Full | ✅ Full | Most flexible | - -**Ubuntu/Linux Host Requirements:** -- Ubuntu 20.04+ or equivalent Linux distribution -- Docker Engine or Docker Desktop -- Python 3.12+ for PyPI installation - ---- - -### Windows Host - -| Installation Method | Requirements | Lume | Winsandbox | Cloud | Notes | -|-------------------|-------------|------|------------|-------|-------| -| **playground-docker.sh** | Docker Desktop + WSL2 | ❌ Not supported | ❌ Not supported | ✅ Full | Requires WSL2 | -| **Dev Container** | VS Code/WindSurf + Docker + WSL2 | ❌ Not supported | ❌ Not supported | ✅ Full | Requires WSL2 | -| **PyPI packages** | Python 3.12+ | ❌ Not supported | ✅ Full | ✅ Full | | - -**Windows Host Requirements:** -- Windows 10/11 with WSL2 enabled for shell script execution -- Docker Desktop with WSL2 backend -- Windows Sandbox feature enabled (for Winsandbox support) -- Python 3.12+ installed in WSL2 or Windows -- **Note**: Lume CLI is not available on Windows - use Cloud or Winsandbox providers - ---- - -## VM Emulation Support - -*This section shows which **virtual machine operating systems** each provider can emulate.* - -| Provider | macOS VM | Ubuntu/Linux VM | Windows VM | Notes | -|----------|----------|-----------------|------------|-------| -| **Lume** | ✅ Full support | ⚠️ Limited support | ⚠️ Limited support | macOS: native; Ubuntu/Linux/Windows: need custom image | -| **Cloud** | 🚧 Coming soon | ✅ Full support | 🚧 Coming soon | Currently Ubuntu only, macOS/Windows in development | -| **Winsandbox** | ❌ Not supported | ❌ Not supported | ✅ Windows only | Windows 10/11 environments only | - ---- - -## Model Provider Compatibility - -*This section shows which **AI model providers** are supported on each host operating system.* - -| Provider | macOS Host | Ubuntu/Linux Host | Windows Host | Notes | -|----------|------------|-------------------|--------------|-------| -| **Anthropic** | ✅ Full support | ✅ Full support | ✅ Full support | Cloud-based API | -| **OpenAI** | ✅ Full support | ✅ Full support | ✅ Full support | Cloud-based API | -| **Ollama** | ✅ Full support | ✅ Full support | ✅ Full support | Local model serving | -| **OpenAI Compatible** | ✅ Full support | ✅ Full support | ✅ Full support | Any OpenAI-compatible API endpoint | -| **MLX VLM** | ✅ macOS only | ❌ Not supported | ❌ Not supported | Apple Silicon required. PyPI installation only. | diff --git a/README.md b/README.md index 9fe22246..8d799d17 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ trycua%2Fcua | Trendshift -**c/ua** ("koo-ah") is Docker for [Computer-Use Agents](https://www.oneusefulthing.org/p/when-you-give-a-claude-a-mouse) - it enables AI agents to control full operating systems in virtual containers and deploy them locally or to the cloud. +**cua** ("koo-ah") is Docker for [Computer-Use Agents](https://www.oneusefulthing.org/p/when-you-give-a-claude-a-mouse) - it enables AI agents to control full operating systems in virtual containers and deploy them locally or to the cloud.
@@ -116,7 +116,7 @@ For detailed compatibility information including host OS support, VM emulation c # 🐍 Usage Guide -Follow these steps to use C/ua in your own Python code. See [Developer Guide](./docs/Developer-Guide.md) for building from source. +Follow these steps to use Cua in your own Python code. See [Developer Guide](./docs/Developer-Guide.md) for building from source. ### Step 1: Install Lume CLI @@ -143,15 +143,16 @@ pip install "cua-computer[all]" "cua-agent[all]" ### Step 4: Use in Your Code ```python +import asyncio from computer import Computer -from agent import ComputerAgent, LLM +from agent import ComputerAgent async def main(): # Start a local macOS VM computer = Computer(os_type="macos") await computer.run() - # Or with C/ua Cloud Container + # Or with Cua Cloud Container computer = Computer( os_type="linux", api_key="your_cua_api_key_here", @@ -228,10 +229,10 @@ docker run -it --rm \ ## Resources -- [How to use the MCP Server with Claude Desktop or other MCP clients](./libs/python/mcp-server/README.md) - One of the easiest ways to get started with C/ua +- [How to use the MCP Server with Claude Desktop or other MCP clients](./libs/python/mcp-server/README.md) - One of the easiest ways to get started with Cua - [How to use OpenAI Computer-Use, Anthropic, OmniParser, or UI-TARS for your Computer-Use Agent](./libs/python/agent/README.md) - [How to use Lume CLI for managing desktops](./libs/lume/README.md) -- [Training Computer-Use Models: Collecting Human Trajectories with C/ua (Part 1)](https://www.trycua.com/blog/training-computer-use-models-trajectories-1) +- [Training Computer-Use Models: Collecting Human Trajectories with Cua (Part 1)](https://www.trycua.com/blog/training-computer-use-models-trajectories-1) - [Build Your Own Operator on macOS (Part 1)](https://www.trycua.com/blog/build-your-own-operator-on-macos-1) ## Modules @@ -317,7 +318,7 @@ await computer.venv_install("demo_venv", ["requests", "macos-pyxa"]) # Install p await computer.venv_cmd("demo_venv", "python -c 'import requests; print(requests.get(`https://httpbin.org/ip`).json())'") # Run a shell command in a virtual environment await computer.venv_exec("demo_venv", python_function_or_code, *args, **kwargs) # Run a Python function in a virtual environment and return the result / raise an exception -# Example: Use sandboxed functions to execute code in a C/ua Container +# Example: Use sandboxed functions to execute code in a Cua Container from computer.helpers import sandboxed @sandboxed("demo_venv") @@ -330,8 +331,8 @@ def greet_and_print(name): return {"greeted": name, "safari_html": html} # When a @sandboxed function is called, it will execute in the container -result = await greet_and_print("C/ua") -# Result: {"greeted": "C/ua", "safari_html": "..."} +result = await greet_and_print("Cua") +# Result: {"greeted": "Cua", "safari_html": "..."} # stdout and stderr are also captured and printed / raised print("Result from sandboxed function:", result) ``` @@ -409,4 +410,4 @@ Thank you to all our supporters! - + \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..55a12ae7 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,28 @@ +# deps +/node_modules + +# generated content +.contentlayer +.content-collections +.source + +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo + +# misc +.DS_Store +*.pem +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# others +.env*.local +.vercel +next-env.d.ts \ No newline at end of file diff --git a/docs/.prettierrc b/docs/.prettierrc new file mode 100644 index 00000000..03af2a8b --- /dev/null +++ b/docs/.prettierrc @@ -0,0 +1,8 @@ +{ + "useTabs": false, + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "bracketSpacing": true, + "jsxBracketSameLine": true +} \ No newline at end of file diff --git a/docs/Developer-Guide.md b/docs/Developer-Guide.md deleted file mode 100644 index 49aa82ee..00000000 --- a/docs/Developer-Guide.md +++ /dev/null @@ -1,293 +0,0 @@ -# Getting Started - -## Project Structure - -The project is organized as a monorepo with these main packages: - -### Python -- `libs/python/core/` - Base package with telemetry support -- `libs/python/computer/` - Computer-use interface (CUI) library -- `libs/python/agent/` - AI agent library with multi-provider support -- `libs/python/som/` - Set-of-Mark parser -- `libs/python/computer-server/` - Server component for VM -- `libs/python/pylume/` - Python bindings for Lume - -### TypeScript -- `libs/typescript/computer/` - Computer-use interface (CUI) library -- `libs/typescript/agent/` - AI agent library with multi-provider support - -### Other -- `libs/lume/` - Lume CLI - -Each package has its own virtual environment and dependencies, managed through PDM. - -## Local Development Setup - -1. Install Lume CLI: - - ```bash - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" - ``` - -2. Clone the repository: - - ```bash - git clone https://github.com/trycua/cua.git - cd cua - ``` - -3. Create a `.env.local` file in the root directory with your API keys: - - ```bash - # Required for Anthropic provider - ANTHROPIC_API_KEY=your_anthropic_key_here - - # Required for OpenAI provider - OPENAI_API_KEY=your_openai_key_here - ``` - -4. Open the workspace in VSCode or Cursor: - - ```bash - # For Cua Python development - code .vscode/py.code-workspace - - # For Lume (Swift) development - code .vscode/lume.code-workspace - ``` - -Using the workspace file is strongly recommended as it: - -- Sets up correct Python environments for each package -- Configures proper import paths -- Enables debugging configurations -- Maintains consistent settings across packages - -## Lume Development - -Refer to the [Lume README](../libs/lume/docs/Development.md) for instructions on how to develop the Lume CLI. - -## Python Development - -There are two ways to install Lume: - -### Run the build script - -Run the build script to set up all packages: - -```bash -./scripts/build.sh -``` - -The build script creates a shared virtual environment for all packages. The workspace configuration automatically handles import paths with the correct Python path settings. - -This will: - -- Create a virtual environment for the project -- Install all packages in development mode -- Set up the correct Python path -- Install development tools - -### Install with PDM - -If PDM is not already installed, you can follow the installation instructions [here](https://pdm-project.org/en/latest/#installation). - -To install with PDM, simply run: - -```console -pdm install -G:all -``` - -This installs all the dependencies for development, testing, and building the docs. If you'd only like development dependencies, you can run: - -```console -pdm install -d -``` - -## Running Examples - -The Python workspace includes launch configurations for all packages: - -- "Run Computer Examples" - Runs computer examples -- "Run Computer API Server" - Runs the computer-server -- "Run Agent Examples" - Runs agent examples -- "SOM" configurations - Various settings for running SOM - -To run examples from VSCode / Cursor: - -1. Press F5 or use the Run/Debug view -2. Select the desired configuration - -The workspace also includes compound launch configurations: - -- "Run Computer Examples + Server" - Runs both the Computer Examples and Server simultaneously - -## Docker Development Environment - -As an alternative to installing directly on your host machine, you can use Docker for development. This approach has several advantages: - -### Prerequisites - -- Docker installed on your machine -- Lume server running on your host (port 7777): `lume serve` - -### Setup and Usage - -1. Build the development Docker image: - - ```bash - ./scripts/run-docker-dev.sh build - ``` - -2. Run an example in the container: - - ```bash - ./scripts/run-docker-dev.sh run computer_examples.py - ``` - -3. Get an interactive shell in the container: - - ```bash - ./scripts/run-docker-dev.sh run --interactive - ``` - -4. Stop any running containers: - - ```bash - ./scripts/run-docker-dev.sh stop - ``` - -### How it Works - -The Docker development environment: - -- Installs all required Python dependencies in the container -- Mounts your source code from the host at runtime -- Automatically configures the connection to use host.docker.internal:7777 for accessing the Lume server on your host machine -- Preserves your code changes without requiring rebuilds (source code is mounted as a volume) - -> **Note**: The Docker container doesn't include the macOS-specific Lume executable. Instead, it connects to the Lume server running on your host machine via host.docker.internal:7777. Make sure to start the Lume server on your host before running examples in the container. - -## Cleanup and Reset - -If you need to clean up the environment (non-docker) and start fresh: - -```bash -./scripts/cleanup.sh -``` - -This will: - -- Remove all virtual environments -- Clean Python cache files and directories -- Remove build artifacts -- Clean PDM-related files -- Reset environment configurations - -## Code Formatting Standards - -The cua project follows strict code formatting standards to ensure consistency across all packages. - -### Python Code Formatting - -#### Tools - -The project uses the following tools for code formatting and linting: - -- **[Black](https://black.readthedocs.io/)**: Code formatter -- **[Ruff](https://beta.ruff.rs/docs/)**: Fast linter and formatter -- **[MyPy](https://mypy.readthedocs.io/)**: Static type checker - -These tools are automatically installed when you set up the development environment using the `./scripts/build.sh` script. - -#### Configuration - -The formatting configuration is defined in the root `pyproject.toml` file: - -```toml -[tool.black] -line-length = 100 -target-version = ["py311"] - -[tool.ruff] -line-length = 100 -target-version = "py311" -select = ["E", "F", "B", "I"] -fix = true - -[tool.ruff.format] -docstring-code-format = true - -[tool.mypy] -strict = true -python_version = "3.11" -ignore_missing_imports = true -disallow_untyped_defs = true -check_untyped_defs = true -warn_return_any = true -show_error_codes = true -warn_unused_ignores = false -``` - -#### Key Formatting Rules - -- **Line Length**: Maximum of 100 characters -- **Python Version**: Code should be compatible with Python 3.11+ -- **Imports**: Automatically sorted (using Ruff's "I" rule) -- **Type Hints**: Required for all function definitions (strict mypy mode) - -#### IDE Integration - -The repository includes VSCode workspace configurations that enable automatic formatting. When you open the workspace files (as recommended in the setup instructions), the correct formatting settings are automatically applied. - -Python-specific settings in the workspace files: - -```json -"[python]": { - "editor.formatOnSave": true, - "editor.defaultFormatter": "ms-python.black-formatter", - "editor.codeActionsOnSave": { - "source.organizeImports": "explicit" - } -} -``` - -Recommended VS Code extensions: - -- Black Formatter (ms-python.black-formatter) -- Ruff (charliermarsh.ruff) -- Pylance (ms-python.vscode-pylance) - -#### Manual Formatting - -To manually format code: - -```bash -# Format all Python files using Black -pdm run black . - -# Run Ruff linter with auto-fix -pdm run ruff check --fix . - -# Run type checking with MyPy -pdm run mypy . -``` - -#### Pre-commit Validation - -Before submitting a pull request, ensure your code passes all formatting checks: - -```bash -# Run all checks -pdm run black --check . -pdm run ruff check . -pdm run mypy . -``` - -### Swift Code (Lume) - -For Swift code in the `libs/lume` directory: - -- Follow the [Swift API Design Guidelines](https://www.swift.org/documentation/api-design-guidelines/) -- Use SwiftFormat for consistent formatting -- Code will be automatically formatted on save when using the lume workspace diff --git a/docs/FAQ.md b/docs/FAQ.md deleted file mode 100644 index e6d77b70..00000000 --- a/docs/FAQ.md +++ /dev/null @@ -1,124 +0,0 @@ -# FAQs - -### Why a local sandbox? - -A local sandbox is a dedicated environment that is isolated from the rest of the system. As AI agents rapidly evolve towards 70-80% success rates on average tasks, having a controlled and secure environment becomes crucial. Cua's Computer-Use AI agents run in a local sandbox to ensure reliability, safety, and controlled execution. - -Benefits of using a local sandbox rather than running the Computer-Use AI agent in the host system: - -- **Reliability**: The sandbox provides a reproducible environment - critical for benchmarking and debugging agent behavior. Frameworks like [OSWorld](https://github.com/xlang-ai/OSWorld), [Simular AI](https://github.com/simular-ai/Agent-S), Microsoft's [OmniTool](https://github.com/microsoft/OmniParser/tree/master/omnitool), [WindowsAgentArena](https://github.com/microsoft/WindowsAgentArena) and more are using Computer-Use AI agents running in local sandboxes. -- **Safety & Isolation**: The sandbox is isolated from the rest of the system, protecting sensitive data and system resources. As CUA agent capabilities grow, this isolation becomes increasingly important for preventing potential safety breaches. -- **Control**: The sandbox can be easily monitored and terminated if needed, providing oversight for autonomous agent operation. - -### Where are the sandbox images stored? - -Sandbox are stored in `~/.lume`, and cached images are stored in `~/.lume/cache`. - -### Which image is Computer using? - -Computer uses an optimized macOS image for Computer-Use interactions, with pre-installed apps and settings for optimal performance. -The image is available on our [ghcr registry](https://github.com/orgs/trycua/packages/container/package/macos-sequoia-cua). - -### Are Sandbox disks taking up all the disk space? - -No, macOS uses sparse files, which only allocate space as needed. For example, VM disks totaling 50 GB may only use 20 GB on disk. - -### How do I delete a VM? - -```bash -lume delete -``` - -### How do I fix EasyOCR `[SSL: CERTIFICATE_VERIFY_FAILED]` errors? - -**Symptom:** -When running an agent that uses OCR (e.g., with `AgentLoop.OMNI`), you might encounter an error during the first run or initialization phase that includes: -``` -ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000) -``` - -**Cause:** -This usually happens when EasyOCR attempts to download its language models over HTTPS for the first time. Python's SSL module cannot verify the server's certificate because it can't locate the necessary root Certificate Authority (CA) certificates in your environment's trust store. - -**Solution:** -You need to explicitly tell Python where to find a trusted CA bundle. The `certifi` package provides one. Before running your Python agent script **the first time it needs to download models**, set the following environment variables in the *same terminal session*: -```bash -# Ensure certifi is installed: pip show certifi -export SSL_CERT_FILE=$(python -m certifi) -export REQUESTS_CA_BUNDLE=$(python -m certifi) - -# Now run your Python script that uses the agent... -# python your_agent_script.py -``` -This directs Python to use the CA bundle provided by `certifi` for SSL verification. **Note:** Once EasyOCR has successfully downloaded its models, you typically do not need to set these environment variables before every subsequent run. - -### How do I troubleshoot the agent failing to get the VM IP address or getting stuck on "VM status changed to: stopped"? - -**Symptom:** -When running your agent script (e.g., using `Computer().run(...)`), the script might hang during the VM startup phase, logging messages like: -* `Waiting for VM to be ready...` -* `VM status changed to: stopped (after 0.0s)` -* `Still waiting for VM IP address... (elapsed: XX.Xs)` -* Eventually, it might time out, or you might notice the VM window never appears or closes quickly. - -**Cause:** -This is typically due to known instability issues with the `lume serve` background daemon process, as documented in the main `README.md`: -1. **`lume serve` Crash:** The `lume serve` process might terminate unexpectedly shortly after launch or when the script tries to interact with it. If it's not running, the script cannot get VM status updates or the IP address. -2. **Incorrect Status Reporting:** Even if `lume serve` is running, its API sometimes incorrectly reports the VM status as `stopped` immediately after startup is initiated. While the underlying `Computer` library tries to poll and wait for the correct `running` status, this initial incorrect report can cause delays or failures if the status doesn't update correctly within the timeout or if `lume serve` crashes during the polling. - -**Troubleshooting Steps:** -1. **Check `lume serve`:** Is the `lume serve` process still running in its terminal? Did it print any errors or exit? If it's not running, stop your agent script (`Ctrl+C`) and proceed to step 2. -2. **Force Cleanup:** Before *every* run, perform a rigorous cleanup to ensure no old `lume` processes or VM states interfere. Open a **new terminal** and run: - ```bash - # Stop any running Lume VM gracefully first (replace if needed) - lume stop macos-sequoia-cua_latest - - # Force kill lume serve and related processes - pkill -f "lume serve" - pkill -9 -f "lume" - pkill -9 -f "VzVirtualMachine" # Kills underlying VM process - - # Optional: Verify they are gone - # ps aux | grep -E 'lume|VzVirtualMachine' | grep -v grep - ``` -3. **Restart Sequence:** - * **Terminal 1:** Start `lume serve` cleanly: - ```bash - lume serve - ``` - *(Watch this terminal to ensure it stays running).* - * **Terminal 2:** Run your agent script (including the `export SSL_CERT_FILE...` commands if *first time* using OCR): - ```bash - # export SSL_CERT_FILE=$(python -m certifi) # Only if first run with OCR - # export REQUESTS_CA_BUNDLE=$(python -m certifi) # Only if first run with OCR - python your_agent_script.py - ``` -4. **Retry:** Due to the intermittent nature of the Lume issues, sometimes simply repeating steps 2 and 3 allows the run to succeed if the timing avoids the status reporting bug or the `lume serve` crash. - -**Related Issue: "No route to host" Error (macOS Sequoia+)** - -* **Symptom:** Even if the `Computer` library logs show the VM has obtained an IP address, you might encounter connection errors like `No route to host` when the agent tries to connect to the internal server, especially when running the agent script from within an IDE (like VS Code or Cursor). -* **Cause:** This is often due to macOS Sequoia's enhanced local network privacy controls. Applications need explicit permission to access the local network, which includes communicating with the VM. -* **Solution:** Grant "Local Network" access to the application you are running the script from (e.g., your IDE or terminal application). Go to **System Settings > Privacy & Security > Local Network**, find your application in the list, and toggle the switch ON. You might need to trigger a connection attempt from the application first for it to appear in the list. See [GitHub Issue #61](https://github.com/trycua/cua/issues/61) for more details and discussion. - -**Note:** Improving the stability of `lume serve` is an ongoing development area. - -### How do I troubleshoot Computer not connecting to lume daemon? - -If you're experiencing connection issues between Computer and the lume daemon, it could be because the port 7777 (used by lume) is already in use by an orphaned process. You can diagnose this issue with: - -```bash -sudo lsof -i :7777 -``` - -This command will show all processes using port 7777. If you see a lume process already running, you can terminate it with: - -```bash -kill -``` - -Where `` is the process ID shown in the output of the `lsof` command. After terminating the process, run `lume serve` again to start the lume daemon. - -### What information does Cua track? - -Cua tracks anonymized usage and error report statistics; we ascribe to Posthog's approach as detailed [here](https://posthog.com/blog/open-source-telemetry-ethical). If you would like to opt out of sending anonymized info, you can set `telemetry_enabled` to false in the Computer or Agent constructor. Check out our [Telemetry](Telemetry.md) documentation for more details. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..b6f494e5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,45 @@ +# docs + +This is a Next.js application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). + +Run development server: + +```bash +npm run dev +# or +pnpm dev +# or +yarn dev +``` + +Open http://localhost:3000 with your browser to see the result. + +## Explore + +In the project, you can see: + +- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content. +- `app/layout.config.tsx`: Shared options for layouts, optional but preferred to keep. + +| Route | Description | +| ------------------------- | ------------------------------------------------------ | +| `app/(home)` | The route group for your landing page and other pages. | +| `app/docs` | The documentation layout and pages. | +| `app/api/search/route.ts` | The Route Handler for search. | + +### Fumadocs MDX + +A `source.config.ts` config file has been included, you can customise different options like frontmatter schema. + +Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details. + +## Learn More + +To learn more about Next.js and Fumadocs, take a look at the following +resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js + features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs diff --git a/docs/Telemetry.md b/docs/Telemetry.md deleted file mode 100644 index 8f85e761..00000000 --- a/docs/Telemetry.md +++ /dev/null @@ -1,74 +0,0 @@ -# Telemetry in CUA - -This document explains how telemetry works in CUA libraries and how you can control it. - -CUA tracks anonymized usage and error report statistics; we ascribe to Posthog's approach as detailed [here](https://posthog.com/blog/open-source-telemetry-ethical). If you would like to opt out of sending anonymized info, you can set `telemetry_enabled` to false. - -## What telemetry data we collect - -CUA libraries collect minimal anonymous usage data to help improve our software. The telemetry data we collect is specifically limited to: - -- Basic system information: - - Operating system (e.g., 'darwin', 'win32', 'linux') - - Python version (e.g., '3.11.0') -- Module initialization events: - - When a module (like 'computer' or 'agent') is imported - - Version of the module being used - -We do NOT collect: -- Personal information -- Contents of files -- Specific text being typed -- Actual screenshots or screen contents -- User-specific identifiers -- API keys -- File contents -- Application data or content -- User interactions with the computer -- Information about files being accessed - -## Controlling Telemetry - -We are committed to transparency and user control over telemetry. There are two ways to control telemetry: - -## 1. Environment Variable (Global Control) - -Telemetry is enabled by default. To disable telemetry, set the `CUA_TELEMETRY_ENABLED` environment variable to a falsy value (`0`, `false`, `no`, or `off`): - -```bash -# Disable telemetry before running your script -export CUA_TELEMETRY_ENABLED=false - -# Or as part of the command -CUA_TELEMETRY_ENABLED=1 python your_script.py - -``` -Or from Python: -```python -import os -os.environ["CUA_TELEMETRY_ENABLED"] = "false" -``` - -## 2. Instance-Level Control - -You can control telemetry for specific CUA instances by setting `telemetry_enabled` when creating them: - -```python -# Disable telemetry for a specific Computer instance -computer = Computer(telemetry_enabled=False) - -# Enable telemetry for a specific Agent instance -agent = ComputerAgent(telemetry_enabled=True) -``` - -You can check if telemetry is enabled for an instance: - -```python -print(computer.telemetry_enabled) # Will print True or False -``` - -Note that telemetry settings must be configured during initialization and cannot be changed after the object is created. - -## Transparency - -We believe in being transparent about the data we collect. If you have any questions about our telemetry practices, please open an issue on our GitHub repository. \ No newline at end of file diff --git a/docs/content/docs/agent-sdk/agent-loops.mdx b/docs/content/docs/agent-sdk/agent-loops.mdx new file mode 100644 index 00000000..bc26cf26 --- /dev/null +++ b/docs/content/docs/agent-sdk/agent-loops.mdx @@ -0,0 +1,39 @@ +--- +title: Agent Loops +description: Supported computer-using agent loops and models +--- + +An agent can be thought of as a loop - it generates actions, executes them, and repeats until done: + +1. **Generate**: Your `model` generates `output_text`, `computer_call`, `function_call` +2. **Execute**: The `computer` safely executes those items +3. **Complete**: If the model has no more calls, it's done! + +To run an agent loop simply do: + +```python +from agent import ComputerAgent +from computer import Computer + +computer = Computer() # Connect to a cua container + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer] +) + +prompt = "open github, navigate to trycua/cua" + +async for result in agent.run(prompt): + if result["output"][-1]["type"] == "message": + print("Agent:", result["output"][-1]["content"][0]["text"]) +``` + +We currently support 4 computer-using agent loops: + +- Anthropic CUAs +- OpenAI CUA Preview +- UI-TARS 1.5 +- Omniparser + LLMs + +For a full list of supported models and configurations, see the [Supported Agents](./supported-agents) page. diff --git a/docs/content/docs/agent-sdk/callbacks/agent-lifecycle.mdx b/docs/content/docs/agent-sdk/callbacks/agent-lifecycle.mdx new file mode 100644 index 00000000..4b75ebcf --- /dev/null +++ b/docs/content/docs/agent-sdk/callbacks/agent-lifecycle.mdx @@ -0,0 +1,52 @@ +--- +title: Agent Lifecycle +description: Agent callback lifecycle and hooks +--- + +# Callbacks + +Callbacks provide hooks into the agent lifecycle for extensibility. They're called in a specific order during agent execution. + +## Callback Lifecycle + +### 1. `on_run_start(kwargs, old_items)` +Called once when agent run begins. Initialize tracking, logging, or state. + +### 2. `on_run_continue(kwargs, old_items, new_items)` → bool +Called before each iteration. Return `False` to stop execution (e.g., budget limits). + +### 3. `on_llm_start(messages)` → messages +Preprocess messages before LLM call. Use for PII anonymization, image retention. + +### 4. `on_api_start(kwargs)` +Called before each LLM API call. + +### 5. `on_api_end(kwargs, result)` +Called after each LLM API call completes. + +### 6. `on_usage(usage)` +Called when usage information is received from LLM. + +### 7. `on_llm_end(messages)` → messages +Postprocess messages after LLM call. Use for PII deanonymization. + +### 8. `on_responses(kwargs, responses)` +Called when responses are received from agent loop. + +### 9. Response-specific hooks: +- `on_text(item)` - Text messages +- `on_computer_call_start(item)` - Before computer actions +- `on_computer_call_end(item, result)` - After computer actions +- `on_function_call_start(item)` - Before function calls +- `on_function_call_end(item, result)` - After function calls +- `on_screenshot(screenshot, name)` - When screenshots are taken + +### 10. `on_run_end(kwargs, old_items, new_items)` +Called when agent run completes. Finalize tracking, save trajectories. + +## Built-in Callbacks + +- **ImageRetentionCallback**: Limits recent images in context +- **BudgetManagerCallback**: Stops execution when budget exceeded +- **TrajectorySaverCallback**: Saves conversation trajectories +- **LoggingCallback**: Logs agent activities diff --git a/docs/content/docs/agent-sdk/callbacks/cost-saving.mdx b/docs/content/docs/agent-sdk/callbacks/cost-saving.mdx new file mode 100644 index 00000000..9a543dc1 --- /dev/null +++ b/docs/content/docs/agent-sdk/callbacks/cost-saving.mdx @@ -0,0 +1,87 @@ +--- +title: Cost Optimization +description: Budget management and image retention for cost optimization +--- + +# Cost Optimization Callbacks + +Optimize agent costs with budget management and image retention callbacks. + +## Budget Manager Callbacks Example + +```python +from agent.callbacks import BudgetManagerCallback + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + callbacks=[ + BudgetManagerCallback( + max_budget=5.0, # $5 limit + reset_after_each_run=False, + raise_error=True + ) + ] +) +``` + +## Budget Manager Shorthand + +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + max_trajectory_budget=5.0 # Auto-adds BudgetManagerCallback +) +``` + +**Or with options:** +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + max_trajectory_budget={"max_budget": 5.0, "raise_error": True} +) +``` + +## Image Retention Callbacks Example + +```python +from agent.callbacks import ImageRetentionCallback + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + callbacks=[ + ImageRetentionCallback(only_n_most_recent_images=3) + ] +) +``` + +## Image Retention Shorthand + +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + only_n_most_recent_images=3 # Auto-adds ImageRetentionCallback +) +``` + +## Combined Cost Optimization + +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + max_trajectory_budget=5.0, # Budget limit + only_n_most_recent_images=3, # Image retention + trajectory_dir="trajectories" # Track spending +) +``` + +## Budget Manager Options + +- `max_budget`: Dollar limit for trajectory +- `reset_after_each_run`: Reset budget per run (default: True) +- `raise_error`: Raise exception vs. graceful stop (default: False) diff --git a/docs/content/docs/agent-sdk/callbacks/logging.mdx b/docs/content/docs/agent-sdk/callbacks/logging.mdx new file mode 100644 index 00000000..8ab9b2e6 --- /dev/null +++ b/docs/content/docs/agent-sdk/callbacks/logging.mdx @@ -0,0 +1,88 @@ +--- +title: Logging +description: Agent logging and custom logger implementation +--- + +# Logging Callback + +Built-in logging callback and custom logger creation for agent monitoring. + +## Callbacks Example + +```python +from agent.callbacks import LoggingCallback +import logging + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + callbacks=[ + LoggingCallback( + logger=logging.getLogger("cua"), + level=logging.INFO + ) + ] +) +``` + +## Shorthand + +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + verbosity=logging.INFO # Auto-adds LoggingCallback +) +``` + +## Custom Logger + +Create custom loggers by extending AsyncCallbackHandler: + +```python +from agent.callbacks.base import AsyncCallbackHandler +import logging + +class CustomLogger(AsyncCallbackHandler): + def __init__(self, logger_name="agent"): + self.logger = logging.getLogger(logger_name) + self.logger.setLevel(logging.INFO) + + # Add console handler + handler = logging.StreamHandler() + formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s' + ) + handler.setFormatter(formatter) + self.logger.addHandler(handler) + + async def on_run_start(self, kwargs, old_items): + self.logger.info(f"Agent run started with model: {kwargs.get('model')}") + + async def on_computer_call_start(self, item): + action = item.get('action', {}) + self.logger.info(f"Computer action: {action.get('type')}") + + async def on_usage(self, usage): + cost = usage.get('response_cost', 0) + self.logger.info(f"API call cost: ${cost:.4f}") + + async def on_run_end(self, kwargs, old_items, new_items): + self.logger.info("Agent run completed") + +# Use custom logger +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + callbacks=[CustomLogger("my_agent")] +) +``` + +## Available Hooks + +Log any agent event using these callback methods: +- `on_run_start/end` - Run lifecycle +- `on_computer_call_start/end` - Computer actions +- `on_api_start/end` - LLM API calls +- `on_usage` - Cost tracking +- `on_screenshot` - Screenshot events diff --git a/docs/content/docs/agent-sdk/callbacks/meta.json b/docs/content/docs/agent-sdk/callbacks/meta.json new file mode 100644 index 00000000..c9a072b0 --- /dev/null +++ b/docs/content/docs/agent-sdk/callbacks/meta.json @@ -0,0 +1,11 @@ +{ + "title": "Callbacks", + "description": "Extending agents with callback hooks and built-in handlers", + "pages": [ + "agent-lifecycle", + "trajectories", + "logging", + "cost-saving", + "pii-anonymization" + ] +} diff --git a/docs/content/docs/agent-sdk/callbacks/pii-anonymization.mdx b/docs/content/docs/agent-sdk/callbacks/pii-anonymization.mdx new file mode 100644 index 00000000..fcfd0861 --- /dev/null +++ b/docs/content/docs/agent-sdk/callbacks/pii-anonymization.mdx @@ -0,0 +1,12 @@ +--- +title: PII Anonymization +description: PII anonymization and data protection callbacks +--- + +# PII Anonymization Callback + +🚧 Coming Soon 🚧 + +🔒 🕵️ 🛡️ 📝 ✨ + +🚀 Stay tuned for PII anonymization features! 🚀 diff --git a/docs/content/docs/agent-sdk/callbacks/trajectories.mdx b/docs/content/docs/agent-sdk/callbacks/trajectories.mdx new file mode 100644 index 00000000..8799c5eb --- /dev/null +++ b/docs/content/docs/agent-sdk/callbacks/trajectories.mdx @@ -0,0 +1,51 @@ +--- +title: Trajectories +description: Recording and viewing agent conversation trajectories +--- + +# Trajectory Saving Callback + +The TrajectorySaverCallback records complete agent conversations including messages, actions, and screenshots for debugging and analysis. + +## Callbacks Example + +```python +from agent.callbacks import TrajectorySaverCallback + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + callbacks=[ + TrajectorySaverCallback( + trajectory_dir="my_trajectories", + save_screenshots=True + ) + ] +) +``` + +## Shorthand + +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + trajectory_dir="trajectories" # Auto-adds TrajectorySaverCallback +) +``` + +## View Trajectories Online + +View trajectories in the browser at: +**[trycua.com/trajectory-viewer](http://trycua.com/trajectory-viewer)** + +The viewer provides: +- Interactive conversation replay +- Screenshot galleries +- No data collection + +## Trajectory Structure + +Each trajectory contains: +- **metadata.json**: Run info, timestamps, usage stats (`total_tokens`, `response_cost`) +- **turn_000/**: Turn-by-turn conversation history (api calls, responses, computer calls, screenshots) diff --git a/docs/content/docs/agent-sdk/chat-history.mdx b/docs/content/docs/agent-sdk/chat-history.mdx new file mode 100644 index 00000000..83435a70 --- /dev/null +++ b/docs/content/docs/agent-sdk/chat-history.mdx @@ -0,0 +1,98 @@ +--- +title: Chat History +description: Managing conversation history and message arrays +--- + +Managing conversation history is essential for multi-turn agent interactions. The agent maintains a messages array that tracks the entire conversation flow. + +## Managing History + +### Continuous Conversation + +```python +history = [] + +while True: + user_input = input("> ") + history.append({"role": "user", "content": user_input}) + + async for result in agent.run(history, stream=False): + history += result["output"] +``` + +## Message Array Structure + +The messages array contains different types of messages that represent the conversation state: + +```python +messages = [ + # user input + { + "role": "user", + "content": "go to trycua on gh" + }, + # first agent turn adds the model output to the history + { + "summary": [ + { + "text": "Searching Firefox for Trycua GitHub", + "type": "summary_text" + } + ], + "type": "reasoning" + }, + { + "action": { + "text": "Trycua GitHub", + "type": "type" + }, + "call_id": "call_QI6OsYkXxl6Ww1KvyJc4LKKq", + "status": "completed", + "type": "computer_call" + }, + # second agent turn adds the computer output to the history + { + "type": "computer_call_output", + "call_id": "call_QI6OsYkXxl6Ww1KvyJc4LKKq", + "output": { + "type": "input_image", + "image_url": "data:image/png;base64,..." + } + }, + # final agent turn adds the agent output text to the history + { + "type": "message", + "role": "assistant", + "content": [ + { + "text": "Success! The Trycua GitHub page has been opened.", + "type": "output_text" + } + ] + } +] +``` + +## Message Types + +- **user**: User input messages +- **computer_call**: Computer actions (click, type, keypress, etc.) +- **computer_call_output**: Results from computer actions (usually screenshots) +- **function_call**: Function calls (e.g., `computer.call`) +- **function_call_output**: Results from function calls +- **reasoning**: Agent's internal reasoning and planning +- **message**: Agent text responses + +### Memory Management + +For long conversations, consider using the `only_n_most_recent_images` parameter to manage memory: + +```python +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + only_n_most_recent_images=3 +) +``` + +This automatically removes old images from the conversation history to prevent context window overflow. diff --git a/docs/content/docs/agent-sdk/local-models.mdx b/docs/content/docs/agent-sdk/local-models.mdx new file mode 100644 index 00000000..347680a8 --- /dev/null +++ b/docs/content/docs/agent-sdk/local-models.mdx @@ -0,0 +1,39 @@ +--- +title: Running Models Locally +--- + +You can run open-source LLMs and vision models on your own machine using cua, without relying on cloud APIs. This is ideal for development, privacy, or running on air-gapped systems. + +## Hugging Face (transformers) + +Use the `huggingface-local/` prefix to run any Hugging Face model locally via the `transformers` library. This supports most text and vision models from the Hugging Face Hub. + +**Example:** + +```python +model = "huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B" +``` + +## MLX (Apple Silicon) + +Use the `mlx/` prefix to run models using the `mlx-vlm` library, optimized for Apple Silicon (M1/M2/M3). This allows fast, local inference for many open-source models. + +**Example:** + +```python +model = "mlx/mlx-community/UI-TARS-1.5-7B-6bit" +``` + +## Ollama + +Use the `ollama_chat/` prefix to run models using the `ollama` library. This allows fast, local inference for many open-source models. + +**Example:** + +```python +model = "omniparser+ollama_chat/llama3.2:latest" +``` + +--- + +For details on all supported providers, see [Supported Agents](./supported-agents). diff --git a/docs/content/docs/agent-sdk/meta.json b/docs/content/docs/agent-sdk/meta.json new file mode 100644 index 00000000..933452cb --- /dev/null +++ b/docs/content/docs/agent-sdk/meta.json @@ -0,0 +1,15 @@ +{ + "title": "Agent SDK", + "description": "Build computer-using agents with the Agent SDK", + "pages": [ + "agent-loops", + "supported-agents", + "chat-history", + "callbacks", + "sandboxed-tools", + "local-models", + "prompt-caching", + "usage-tracking", + "migration-guide" + ] +} diff --git a/docs/content/docs/agent-sdk/migration-guide.mdx b/docs/content/docs/agent-sdk/migration-guide.mdx new file mode 100644 index 00000000..89ee706e --- /dev/null +++ b/docs/content/docs/agent-sdk/migration-guide.mdx @@ -0,0 +1,124 @@ +--- +title: Migration Guide +--- + +This guide lists **breaking changes** when migrating from the original `ComputerAgent` (v0.3.x) to the rewritten `ComputerAgent` (v0.4.x) and shows old vs new usage for all four agent loops. + +## Breaking Changes + +- **Initialization:** + - `ComputerAgent` (v0.4.x) uses `model` as a string (e.g. "anthropic/claude-3-5-sonnet-20241022") instead of `LLM` and `AgentLoop` objects. + - `tools` is a list (can include multiple computers and decorated functions). + - `callbacks` are now first-class for extensibility (image retention, budget, trajectory, logging, etc). +- **No explicit `loop` parameter:** + - Loop is inferred from the `model` string (e.g. `anthropic/`, `openai/`, `omniparser+`, `ui-tars`). +- **No explicit `computer` parameter:** + - Computers are added to `tools` list. + +--- + +## Usage Examples: Old vs New + +### 1. Anthropic Loop +**Old:** +```python +async with Computer() as computer: + agent = ComputerAgent( + computer=computer, + loop=AgentLoop.ANTHROPIC, + model=LLM(provider=LLMProvider.ANTHROPIC) + ) + async for result in agent.run("Take a screenshot"): + print(result) +``` +**New:** +```python +async with Computer() as computer: + agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer] + ) + messages = [{"role": "user", "content": "Take a screenshot"}] + async for result in agent.run(messages): + for item in result["output"]: + if item["type"] == "message": + print(item["content"][0]["text"]) +``` + +### 2. OpenAI Loop +**Old:** +```python +async with Computer() as computer: + agent = ComputerAgent( + computer=computer, + loop=AgentLoop.OPENAI, + model=LLM(provider=LLMProvider.OPENAI) + ) + async for result in agent.run("Take a screenshot"): + print(result) +``` +**New:** +```python +async with Computer() as computer: + agent = ComputerAgent( + model="openai/computer-use-preview", + tools=[computer] + ) + messages = [{"role": "user", "content": "Take a screenshot"}] + async for result in agent.run(messages): + for item in result["output"]: + if item["type"] == "message": + print(item["content"][0]["text"]) +``` + +### 3. UI-TARS Loop +**Old:** +```python +async with Computer() as computer: + agent = ComputerAgent( + computer=computer, + loop=AgentLoop.UITARS, + model=LLM(provider=LLMProvider.OAICOMPAT, name="ByteDance-Seed/UI-TARS-1.5-7B", provider_base_url="https://.../v1") + ) + async for result in agent.run("Take a screenshot"): + print(result) +``` +**New:** +```python +async with Computer() as computer: + agent = ComputerAgent( + model="huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B", + tools=[computer] + ) + messages = [{"role": "user", "content": "Take a screenshot"}] + async for result in agent.run(messages): + for item in result["output"]: + if item["type"] == "message": + print(item["content"][0]["text"]) +``` + +### 4. Omni Loop +**Old:** +```python +async with Computer() as computer: + agent = ComputerAgent( + computer=computer, + loop=AgentLoop.OMNI, + model=LLM(provider=LLMProvider.OLLAMA, name="gemma3") + ) + async for result in agent.run("Take a screenshot"): + print(result) +``` +**New:** +```python +async with Computer() as computer: + agent = ComputerAgent( + model="omniparser+ollama_chat/gemma3", + tools=[computer] + ) + messages = [{"role": "user", "content": "Take a screenshot"}] + async for result in agent.run(messages): + for item in result["output"]: + if item["type"] == "message": + print(item["content"][0]["text"]) +``` diff --git a/docs/content/docs/agent-sdk/prompt-caching.mdx b/docs/content/docs/agent-sdk/prompt-caching.mdx new file mode 100644 index 00000000..4c69f99f --- /dev/null +++ b/docs/content/docs/agent-sdk/prompt-caching.mdx @@ -0,0 +1,54 @@ +--- +title: Prompt Caching +sidebar_position: 8 +description: How to use prompt caching in ComputerAgent and agent loops. +--- + +Prompt caching is a cost-saving feature offered by some LLM API providers that helps avoid reprocessing the same prompt, improving efficiency and reducing costs for repeated or long-running tasks. + +## Usage + +The `use_prompt_caching` argument is available for `ComputerAgent` and agent loops: + +```python +agent = ComputerAgent( + ..., + use_prompt_caching=True, +) +``` + +- **Type:** `bool` +- **Default:** `False` +- **Purpose:** Use prompt caching to avoid reprocessing the same prompt. + +## Anthropic CUAs + +When using Anthropic-based CUAs (Claude models), setting `use_prompt_caching=True` will automatically add `{ "cache_control": "ephemeral" }` to your messages. This enables prompt caching for the session and can speed up repeated runs with the same prompt. + +> **Note:** This argument is only required for Anthropic CUAs. For other providers, it is ignored. + +## OpenAI Provider + +With the OpenAI provider, prompt caching is handled automatically for prompts of 1000+ tokens. You do **not** need to set `use_prompt_caching`—caching will occur for long prompts without any extra configuration. + +## Example + +```python +from agent import ComputerAgent +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20240620", + use_prompt_caching=True, +) +``` + +## Implementation Details +- For Anthropic: Adds `{ "cache_control": "ephemeral" }` to messages when enabled. +- For OpenAI: Caching is automatic for long prompts; the argument is ignored. + +## When to Use +- Enable for Anthropic CUAs if you want to avoid reprocessing the same prompt in repeated or iterative tasks. +- Not needed for OpenAI models unless you want explicit ephemeral cache control (not required for most users). + +## See Also +- [Agent Loops](./agent-loops) +- [Migration Guide](./migration-guide) diff --git a/docs/content/docs/agent-sdk/sandboxed-tools.mdx b/docs/content/docs/agent-sdk/sandboxed-tools.mdx new file mode 100644 index 00000000..0d71f8ef --- /dev/null +++ b/docs/content/docs/agent-sdk/sandboxed-tools.mdx @@ -0,0 +1,31 @@ +--- +title: Sandboxed Tools +slug: sandboxed-tools +--- + +The Agent SDK supports defining custom Python tools that run securely in sandboxed environments on remote Cua Computers. This enables safe execution of user-defined functions, isolation of dependencies, and robust automation workflows. + +## Example: Defining a Sandboxed Tool + +```python +from computer.helpers import sandboxed + +@sandboxed() +def read_file(location: str) -> str: + """Read contents of a file""" + with open(location, 'r') as f: + return f.read() +``` + +You can then register this as a tool for your agent: + +```python +from agent import ComputerAgent +from computer import Computer + +computer = Computer(...) +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20240620", + tools=[computer, read_file], +) +``` diff --git a/docs/content/docs/agent-sdk/supported-agents.mdx b/docs/content/docs/agent-sdk/supported-agents.mdx new file mode 100644 index 00000000..61abf521 --- /dev/null +++ b/docs/content/docs/agent-sdk/supported-agents.mdx @@ -0,0 +1,34 @@ +--- +title: Supported Agents +--- + +This page lists all supported agent loops and their compatible models/configurations in cua. + +All agent loops are compatible with any LLM provider supported by LiteLLM. + +See [Running Models Locally](./local-models) for how to use Hugging Face and MLX models on your own machine. + +## Anthropic CUAs + +- Claude 4: `claude-opus-4-20250514`, `claude-sonnet-4-20250514` +- Claude 3.7: `claude-3-7-sonnet-20250219` +- Claude 3.5: `claude-3-5-sonnet-20240620` + +## OpenAI CUA Preview + +- Computer-use-preview: `computer-use-preview` + +## UI-TARS 1.5 + +- `huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B` +- `huggingface/ByteDance-Seed/UI-TARS-1.5-7B` (requires TGI endpoint) + +## Omniparser + LLMs + +- `omniparser+vertex_ai/gemini-pro` +- `omniparser+openai/gpt-4o` +- Any LiteLLM-compatible model combined with Omniparser + +--- + +For details on agent loop behavior and usage, see [Agent Loops](./agent-loops). diff --git a/docs/content/docs/agent-sdk/usage-tracking.mdx b/docs/content/docs/agent-sdk/usage-tracking.mdx new file mode 100644 index 00000000..54bbcaae --- /dev/null +++ b/docs/content/docs/agent-sdk/usage-tracking.mdx @@ -0,0 +1,63 @@ +--- +title: Usage Tracking +sidebar_position: 9 +description: How to track token usage and cost in ComputerAgent and agent loops. +--- + +Tracking usage is important for monitoring costs and optimizing your agent workflows. The ComputerAgent API provides easy access to token and cost usage for every run. + +## Accessing Usage Data + +Whenever you run an agent loop, each result contains a `usage` dictionary with token and cost information: + +```python +async for result in agent.run(...): + print(result["usage"]) + # Example output: + # { + # "prompt_tokens": 150, + # "completion_tokens": 75, + # "total_tokens": 225, + # "response_cost": 0.01, + # } +``` + +- `prompt_tokens`: Number of tokens in the prompt +- `completion_tokens`: Number of tokens in the agent's response +- `total_tokens`: Total tokens used +- `response_cost`: Estimated cost (USD) for this turn + +## Tracking Total Usage + +You can accumulate usage across multiple turns: + +```python +total_usage = {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0, "response_cost": 0.0} +async for result in agent.run(...): + for k in total_usage: + total_usage[k] += result["usage"].get(k, 0) +print("Total usage:", total_usage) +``` + +## Using Callbacks for Usage Tracking + +You can also use a callback to automatically track usage. Implement the `on_usage` method in your callback class: + +```python +from agent.callbacks import AsyncCallbackHandler + +class UsageTrackerCallback(AsyncCallbackHandler): + async def on_usage(self, usage): + print("Usage update:", usage) + +agent = ComputerAgent( + ..., + callbacks=[UsageTrackerCallback()] +) +``` + +See also: [Budget Manager Callbacks](./callbacks#cost-saving) + +## See Also +- [Prompt Caching](./prompt-caching) +- [Callbacks](./callbacks) diff --git a/docs/content/docs/computer-sdk/commands.mdx b/docs/content/docs/computer-sdk/commands.mdx new file mode 100644 index 00000000..dbac237f --- /dev/null +++ b/docs/content/docs/computer-sdk/commands.mdx @@ -0,0 +1,248 @@ +--- +title: Commands +description: Computer commands and interface methods +--- + +This page describes the set of supported **commands** you can use to control a Cua Computer directly via the Python SDK. + +These commands map to the same actions available in the [Computer Server API Commands Reference](../libraries/computer-server/Commands), and provide low-level, async access to system operations from your agent or automation code. + +## Shell Actions + +Execute shell commands and get detailed results: + + + + ```python # Run shell command result = await + computer.interface.run_command(cmd) # result.stdout, result.stderr, + result.returncode ``` + + + ```typescript // Run shell command const result = await + computer.interface.runCommand(cmd); // result.stdout, result.stderr, + result.returncode ``` + + + +## Mouse Actions + +Precise mouse control and interaction: + + + + ```python + # Basic clicks + await computer.interface.left_click(x, y) # Left click at coordinates + await computer.interface.right_click(x, y) # Right click at coordinates + await computer.interface.double_click(x, y) # Double click at coordinates + + # Cursor movement and dragging + await computer.interface.move_cursor(x, y) # Move cursor to coordinates + await computer.interface.drag_to(x, y, duration) # Drag to coordinates + await computer.interface.get_cursor_position() # Get current cursor position + + # Advanced mouse control + await computer.interface.mouse_down(x, y, button="left") # Press and hold a mouse button + await computer.interface.mouse_up(x, y, button="left") # Release a mouse button + ``` + + + + ```typescript + // Basic clicks + await computer.interface.leftClick(x, y); // Left click at coordinates + await computer.interface.rightClick(x, y); // Right click at coordinates + await computer.interface.doubleClick(x, y); // Double click at coordinates + + // Cursor movement and dragging + await computer.interface.moveCursor(x, y); // Move cursor to coordinates + await computer.interface.dragTo(x, y, duration); // Drag to coordinates + await computer.interface.getCursorPosition(); // Get current cursor position + + // Advanced mouse control + await computer.interface.mouseDown(x, y, "left"); // Press and hold a mouse button + await computer.interface.mouseUp(x, y, "left"); // Release a mouse button + ``` + + + + +## Keyboard Actions + +Text input and key combinations: + + + + ```python + # Text input + await computer.interface.type_text("Hello") # Type text + await computer.interface.press_key("enter") # Press a single key + + # Key combinations and advanced control + await computer.interface.hotkey("command", "c") # Press key combination + await computer.interface.key_down("command") # Press and hold a key + await computer.interface.key_up("command") # Release a key + ``` + + + + ```typescript + // Text input + await computer.interface.typeText("Hello"); // Type text + await computer.interface.pressKey("enter"); // Press a single key + + // Key combinations and advanced control + await computer.interface.hotkey("command", "c"); // Press key combination + await computer.interface.keyDown("command"); // Press and hold a key + await computer.interface.keyUp("command"); // Release a key + ``` + + + + +## Scrolling Actions + +Mouse wheel and scrolling control: + + + + + ```python + # Scrolling + await computer.interface.scroll(x, y) # Scroll the mouse wheel + await computer.interface.scroll_down(clicks) # Scroll down await + computer.interface.scroll_up(clicks) # Scroll up + + ``` + + + + ```typescript + // Scrolling + await computer.interface.scroll(x, y); // Scroll the mouse wheel + await computer.interface.scrollDown(clicks); // Scroll down + await computer.interface.scrollUp(clicks); // Scroll up + + ``` + + + +## Screen Actions + +Screen capture and display information: + + + + ```python + # Screen operations + await computer.interface.screenshot() # Take a screenshot + await computer.interface.get_screen_size() # Get screen dimensions + + ``` + + + + ```typescript + // Screen operations + await computer.interface.screenshot(); // Take a screenshot + await computer.interface.getScreenSize(); // Get screen dimensions + + ``` + + + +## Clipboard Actions + +System clipboard management: + + + + ```python + # Clipboard operations await + computer.interface.set_clipboard(text) # Set clipboard content await + computer.interface.copy_to_clipboard() # Get clipboard content + + ``` + + + + ```typescript + // Clipboard operations + await computer.interface.setClipboard(text); // Set clipboard content + await computer.interface.copyToClipboard(); // Get clipboard content + + ``` + + + + +## File System Operations + +Direct file and directory manipulation: + + + + + ```python + # File existence checks + await computer.interface.file_exists(path) # Check if file exists + await computer.interface.directory_exists(path) # Check if directory exists + + # File content operations + await computer.interface.read_text(path, encoding="utf-8") # Read file content + await computer.interface.write_text(path, content, encoding="utf-8") # Write file content + await computer.interface.read_bytes(path) # Read file content as bytes + await computer.interface.write_bytes(path, content) # Write file content as bytes + + # File and directory management + await computer.interface.delete_file(path) # Delete file + await computer.interface.create_dir(path) # Create directory + await computer.interface.delete_dir(path) # Delete directory + await computer.interface.list_dir(path) # List directory contents + ``` + + + + ```typescript + // File existence checks + await computer.interface.fileExists(path); // Check if file exists + await computer.interface.directoryExists(path); // Check if directory exists + + // File content operations + await computer.interface.readText(path, "utf-8"); // Read file content + await computer.interface.writeText(path, content, "utf-8"); // Write file content + await computer.interface.readBytes(path); // Read file content as bytes + await computer.interface.writeBytes(path, content); // Write file content as bytes + + // File and directory management + await computer.interface.deleteFile(path); // Delete file + await computer.interface.createDir(path); // Create directory + await computer.interface.deleteDir(path); // Delete directory + await computer.interface.listDir(path); // List directory contents + ``` + + + + +## Accessibility + +Access system accessibility information: + + + + ```python + # Get accessibility tree + await computer.interface.get_accessibility_tree() + + ``` + + + + ```typescript + // Get accessibility tree + await computer.interface.getAccessibilityTree(); + +``` + + +``` diff --git a/docs/content/docs/computer-sdk/computers.mdx b/docs/content/docs/computer-sdk/computers.mdx new file mode 100644 index 00000000..470e8a65 --- /dev/null +++ b/docs/content/docs/computer-sdk/computers.mdx @@ -0,0 +1,102 @@ +--- +title: Cua Computers +description: Understanding cua computer types and connection methods +--- + +Before we can automate apps using AI, we need to first connect to a Computer Server to give the AI a safe environment to execute workflows in. + +Cua Computers are preconfigured virtual machines running the Computer Server. They can be either macOS, Linux, or Windows. They're found in either a cloud-native container, or on your host desktop. + +## cua cloud container + +This is a cloud container running the Computer Server. This is the easiest & safest way to get a cua computer, and can be done by going on the trycua.com website. + + + + ```python + from computer import Computer + + computer = Computer( + os_type="linux", + provider_type="cloud", + name="your-container-name", + api_key="your-api-key" + ) + + await computer.run() # Connect to the container + ``` + + + + ```typescript + import { Computer, OSType } from '@trycua/computer'; + + const computer = new Computer({ + osType: OSType.LINUX, + name: "your-container-name", + apiKey: "your-api-key" + }); + + await computer.run(); // Connect to the container + ``` + + + + +## cua local containers + +cua provides local containers. This can be done using either the Lume CLI (macOS) or Docker CLI (Linux, Windows). + +### Lume (macOS Only): + +1. Install lume cli + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" +``` + +2. Start a local cua container + +```bash +lume run macos-sequoia-cua:latest +``` + +3. Connect with Computer + + + + ```python + computer = Computer( + os_type="macos", + provider_type="lume", + name="macos-sequoia-cua:latest" + ) + + await computer.run() # Connect to the container + ``` + + + + +## Your host desktop + +You can also have agents control your desktop directly by running Computer Server without any containerization layer. Beware that AI models may perform risky actions. + +```bash +pip install cua-computer-server +python -m computer-server +``` + +Connect with: + + + + ```python + + computer = Computer(use_host_computer_server=True) await + computer.run() # Connect to the host desktop + + ``` + + + diff --git a/docs/content/docs/computer-sdk/meta.json b/docs/content/docs/computer-sdk/meta.json new file mode 100644 index 00000000..f632538b --- /dev/null +++ b/docs/content/docs/computer-sdk/meta.json @@ -0,0 +1,9 @@ +{ + "title": "Computer SDK", + "description": "Build computer-using agents with the Computer SDK", + "pages": [ + "computers", + "commands", + "sandboxed-python" + ] +} diff --git a/docs/content/docs/computer-sdk/sandboxed-python.mdx b/docs/content/docs/computer-sdk/sandboxed-python.mdx new file mode 100644 index 00000000..1e7f6b78 --- /dev/null +++ b/docs/content/docs/computer-sdk/sandboxed-python.mdx @@ -0,0 +1,49 @@ +--- +title: Sandboxed Python +slug: sandboxed-python +--- + +You can run Python functions securely inside a sandboxed virtual environment on a remote Cua Computer. This is useful for executing untrusted user code, isolating dependencies, or providing a safe environment for automation tasks. + +## How It Works + +The `sandboxed` decorator from the Computer SDK wraps a Python function so that it is executed remotely in a specified virtual environment on the target Computer. The function and its arguments are serialized, sent to the remote, and executed in isolation. Results or errors are returned to the caller. + +## Example Usage + +```python +from computer import Computer +from computer.helpers import sandboxed + +@sandboxed() +def read_file(location: str) -> str: + """Read contents of a file""" + with open(location, 'r') as f: + return f.read() + +async def main(): + async with Computer(os_type="linux", provider_type="cloud", name="my-container", api_key="...") as computer: + # Call the sandboxed function (runs remotely) + result = await read_file("/etc/hostname") + print(result) +``` + +## Installing Python Packages + +You can specify the virtual environment name and target computer: + +```python +@sandboxed(venv_name="myenv", computer=my_computer, max_retries=5) +def my_function(...): + ... +``` + +You can also install packages in the virtual environment using the `venv_install` method: + +```python +await my_computer.venv_install("myenv", ["requests"]) +``` + +## Error Handling + +If the remote execution fails, the decorator will retry up to `max_retries` times. If all attempts fail, the last exception is raised locally. diff --git a/docs/content/docs/index.mdx b/docs/content/docs/index.mdx new file mode 100644 index 00000000..22d5986e --- /dev/null +++ b/docs/content/docs/index.mdx @@ -0,0 +1,30 @@ +--- +title: Home +icon: House +--- + +import { Monitor, Code, BookOpen } from 'lucide-react'; + +# Welcome! + +Cua is a framework for automating Windows, Mac, and Linux apps powered by computer-using agents (CUAs). + +Cua makes every stage of computer-using agent development simple: + +- **Development**: Use any LLM provider with liteLLM. The agent SDK makes multiple agent loop providers, trajectory tracing, caching, and budget management easy +- **Containerization**: cua offers Docker containers pre-installed with everything needed for AI-powered RPA +- **Deployment**: cua cloud gives you a production-ready cloud environment for your assistants + +
+ } href="/quickstart-ui" title="Quickstart (UI)"> + Try the cua Agent UI in your browser—no coding required. + + } href="/quickstart-devs" title="Quickstart (Developers)"> + Build with Python—full SDK and agent code examples. + +
+
+ } href="/libraries/agent" title="API Reference"> + Explore the agent SDK and APIs + +
diff --git a/docs/content/docs/libraries/agent/index.mdx b/docs/content/docs/libraries/agent/index.mdx new file mode 100644 index 00000000..177f1b10 --- /dev/null +++ b/docs/content/docs/libraries/agent/index.mdx @@ -0,0 +1,125 @@ +--- +title: Agent +description: Reference for the current version of the Agent library. +pypi: cua-agent +github: + - https://github.com/trycua/cua/tree/main/libs/python/agent +--- + +The Agent library provides the ComputerAgent class and tools for building AI agents that automate workflows on Cua Computers. + +## Reference + +### Basic Usage + +```python +from agent import ComputerAgent +from computer import Computer + +computer = Computer() # Connect to a cua container +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer] +) + +prompt = "open github, navigate to trycua/cua" + +async for result in agent.run(prompt): + print("Agent:", result["output"][-1]["content"][0]["text"]) +``` + +--- + +### ComputerAgent Constructor Options + +The `ComputerAgent` constructor provides a wide range of options for customizing agent behavior, tool integration, callbacks, resource management, and more. + +| Parameter | Type | Default | Description | +| --------------------------- | ----------------- | ------------ | ---------------------------------------------------------------------------------------------------- | +| `model` | `str` | **required** | Model name (e.g., "claude-3-5-sonnet-20241022", "computer-use-preview", "omni+vertex_ai/gemini-pro") | +| `tools` | `List[Any]` | `None` | List of tools (e.g., computer objects, decorated functions) | +| `custom_loop` | `Callable` | `None` | Custom agent loop function (overrides auto-selection) | +| `only_n_most_recent_images` | `int` | `None` | If set, only keep the N most recent images in message history (adds ImageRetentionCallback) | +| `callbacks` | `List[Any]` | `None` | List of AsyncCallbackHandler instances for preprocessing/postprocessing | +| `verbosity` | `int` | `None` | Logging level (`logging.DEBUG`, `logging.INFO`, etc.; adds LoggingCallback) | +| `trajectory_dir` | `str` | `None` | Directory to save trajectory data (adds TrajectorySaverCallback) | +| `max_retries` | `int` | `3` | Maximum number of retries for failed API calls | +| `screenshot_delay` | `float` \| `int` | `0.5` | Delay before screenshots (seconds) | +| `use_prompt_caching` | `bool` | `False` | Use prompt caching to avoid reprocessing the same prompt (mainly for Anthropic) | +| `max_trajectory_budget` | `float` \| `dict` | `None` | If set, adds BudgetManagerCallback to track usage costs and stop when budget is exceeded | +| `**kwargs` | _any_ | | Additional arguments passed to the agent loop | + +#### Parameter Details + +- **model**: The LLM or agent model to use. Determines which agent loop is selected unless `custom_loop` is provided. +- **tools**: List of tools the agent can use (e.g., `Computer`, sandboxed Python functions, etc.). +- **custom_loop**: Optional custom agent loop function. If provided, overrides automatic loop selection. +- **only_n_most_recent_images**: If set, only the N most recent images are kept in the message history. Useful for limiting memory usage. Automatically adds `ImageRetentionCallback`. +- **callbacks**: List of callback instances for advanced preprocessing, postprocessing, logging, or custom hooks. See [Callbacks & Extensibility](#callbacks--extensibility). +- **verbosity**: Logging level (e.g., `logging.INFO`). If set, adds a logging callback. +- **trajectory_dir**: Directory path to save full trajectory data, including screenshots and responses. Adds `TrajectorySaverCallback`. +- **max_retries**: Maximum number of retries for failed API calls (default: 3). +- **screenshot_delay**: Delay (in seconds) before taking screenshots (default: 0.5). +- **use_prompt_caching**: Enables prompt caching for repeated prompts (mainly for Anthropic models). +- **max_trajectory_budget**: If set (float or dict), adds a budget manager callback that tracks usage costs and stops execution if the budget is exceeded. Dict allows advanced options (e.g., `{ "max_budget": 5.0, "raise_error": True }`). +- **\*\*kwargs**: Any additional keyword arguments are passed through to the agent loop or model provider. + +**Example with advanced options:** + +```python +from agent import ComputerAgent +from computer import Computer +from agent.callbacks import ImageRetentionCallback + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[Computer(...)], + only_n_most_recent_images=3, + callbacks=[ImageRetentionCallback(only_n_most_recent_images=3)], + verbosity=logging.INFO, + trajectory_dir="trajectories", + max_retries=5, + screenshot_delay=1.0, + use_prompt_caching=True, + max_trajectory_budget={"max_budget": 5.0, "raise_error": True} +) +``` + +--- + +### Message Array (Multi-turn) + +```python +messages = [ + {"role": "user", "content": "go to trycua on gh"}, + # ... (reasoning, computer_call, computer_call_output, etc) +] +async for result in agent.run(messages): + # Handle output, tool invocations, screenshots, etc. + print("Agent:", result["output"][-1]["content"][0]["text"]) + messages += result["output"] # Add agent output to message array + ... +``` + +### Supported Agent Loops + +- **Anthropic**: Claude 4, 3.7, 3.5 models +- **OpenAI**: computer-use-preview +- **UITARS**: UI-TARS 1.5 models (Hugging Face, TGI) +- **Omni**: Omniparser + any LLM + +See [Agent Loops](../../agent-sdk/agent-loops) for supported models and details. + +### Callbacks & Extensibility + +You can add preprocessing and postprocessing hooks using callbacks, or write your own by subclassing `AsyncCallbackHandler`: + +```python +from agent.callbacks import ImageRetentionCallback, PIIAnonymizationCallback + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + callbacks=[ImageRetentionCallback(only_n_most_recent_images=3)] +) +``` diff --git a/docs/content/docs/libraries/computer-server/Commands.mdx b/docs/content/docs/libraries/computer-server/Commands.mdx new file mode 100644 index 00000000..269162a1 --- /dev/null +++ b/docs/content/docs/libraries/computer-server/Commands.mdx @@ -0,0 +1,48 @@ +--- +title: Supported Commands +description: List of all commands supported by the Computer Server API (WebSocket and REST). +--- + +# Commands Reference + +This page lists all supported commands for the Computer Server, available via both WebSocket and REST API endpoints. + +| Command | Description | +|---------------------|--------------------------------------------| +| version | Get protocol and package version info | +| run_command | Run a shell command | +| screenshot | Capture a screenshot | +| get_screen_size | Get the screen size | +| get_cursor_position | Get the current mouse cursor position | +| mouse_down | Mouse button down | +| mouse_up | Mouse button up | +| left_click | Left mouse click | +| right_click | Right mouse click | +| double_click | Double mouse click | +| move_cursor | Move mouse cursor to coordinates | +| drag_to | Drag mouse to coordinates | +| drag | Drag mouse by offset | +| key_down | Keyboard key down | +| key_up | Keyboard key up | +| type_text | Type text | +| press_key | Press a single key | +| hotkey | Press a hotkey combination | +| scroll | Scroll the screen | +| scroll_down | Scroll down | +| scroll_up | Scroll up | +| copy_to_clipboard | Copy text to clipboard | +| set_clipboard | Set clipboard content | +| file_exists | Check if a file exists | +| directory_exists | Check if a directory exists | +| list_dir | List files/directories in a directory | +| read_text | Read text from a file | +| write_text | Write text to a file | +| read_bytes | Read bytes from a file | +| write_bytes | Write bytes to a file | +| get_file_size | Get file size | +| delete_file | Delete a file | +| create_dir | Create a directory | +| delete_dir | Delete a directory | +| get_accessibility_tree | Get accessibility tree (if supported) | +| find_element | Find element in accessibility tree | +| diorama_cmd | Run a diorama command (if supported) | diff --git a/docs/content/docs/libraries/computer-server/REST-API.mdx b/docs/content/docs/libraries/computer-server/REST-API.mdx new file mode 100644 index 00000000..369565de --- /dev/null +++ b/docs/content/docs/libraries/computer-server/REST-API.mdx @@ -0,0 +1,63 @@ +--- +title: REST API Reference +description: Reference for the /cmd REST endpoint of the Computer Server. +--- + +# REST API Reference + +The Computer Server exposes a single REST endpoint for command execution: + +- `http://localhost:8000/cmd` +- `https://your-container.containers.cloud.trycua.com:8443/cmd` (cloud) + +## POST /cmd + +- Accepts commands as JSON in the request body +- Returns results as a streaming response (text/event-stream) + +### Request Format +```json +{ + "command": "", + "params": { ... } +} +``` + +### Required Headers (for cloud containers) +- `X-Container-Name`: Name of the container (cloud only) +- `X-API-Key`: API key for authentication (cloud only) + +### Example Request (Python) +```python +import requests + +url = "http://localhost:8000/cmd" +body = {"command": "screenshot", "params": {}} +resp = requests.post(url, json=body) +print(resp.text) +``` + +### Example Request (Cloud) +```python +import requests + +url = "https://your-container.containers.cloud.trycua.com:8443/cmd" +headers = { + "X-Container-Name": "your-container", + "X-API-Key": "your-api-key" +} +body = {"command": "screenshot", "params": {}} +resp = requests.post(url, json=body, headers=headers) +print(resp.text) +``` + +### Response Format +Streaming text/event-stream with JSON objects, e.g.: +``` +data: {"success": true, "content": "..."} + +data: {"success": false, "error": "..."} +``` + +### Supported Commands +See [Commands Reference](./Commands) for the full list of commands and parameters. diff --git a/docs/content/docs/libraries/computer-server/WebSocket-API.mdx b/docs/content/docs/libraries/computer-server/WebSocket-API.mdx new file mode 100644 index 00000000..98d6d7ad --- /dev/null +++ b/docs/content/docs/libraries/computer-server/WebSocket-API.mdx @@ -0,0 +1,86 @@ +--- +title: WebSocket API Reference +description: Reference for the /ws WebSocket endpoint of the Computer Server. +--- + +# WebSocket API Reference + +The Computer Server exposes a WebSocket endpoint for real-time command execution and streaming results. + +- `ws://localhost:8000/ws` +- `wss://your-container.containers.cloud.trycua.com:8443/ws` (cloud) + +### Authentication (Cloud Only) +For cloud containers, you must authenticate immediately after connecting: +```json +{ + "command": "authenticate", + "params": { + "container_name": "your-container", + "api_key": "your-api-key" + } +} +``` +If authentication fails, the connection is closed. + +### Command Format +Send JSON messages: +```json +{ + "command": "", + "params": { ... } +} +``` + +### Example (Python) +```python +import websockets +import asyncio +import json + +async def main(): + uri = "ws://localhost:8000/ws" + async with websockets.connect(uri) as ws: + await ws.send(json.dumps({"command": "version", "params": {}})) + response = await ws.recv() + print(response) + +asyncio.run(main()) +``` + +### Example (Cloud) +```python +import websockets +import asyncio +import json + +async def main(): + uri = "wss://your-container.containers.cloud.trycua.com:8443/ws" + async with websockets.connect(uri) as ws: + await ws.send(json.dumps({ + "command": "authenticate", + "params": { + "container_name": "your-container", + "api_key": "your-api-key" + } + })) + auth_response = await ws.recv() + print(auth_response) + await ws.send(json.dumps({"command": "version", "params": {}})) + response = await ws.recv() + print(response) + +asyncio.run(main()) +``` + +### Response Format +Each response is a JSON object: +```json +{ + "success": true, + ... +} +``` + +### Supported Commands +See [Commands Reference](./Commands) for the full list of commands and parameters. diff --git a/docs/content/docs/libraries/computer-server/index.mdx b/docs/content/docs/libraries/computer-server/index.mdx new file mode 100644 index 00000000..c2a9c43c --- /dev/null +++ b/docs/content/docs/libraries/computer-server/index.mdx @@ -0,0 +1,13 @@ +--- +title: Computer Server +descrption: Reference for the current version of the Computer Server library. +pypi: cua-computer-server +github: + - https://github.com/trycua/cua/tree/main/libs/python/computer-server +--- + +The Computer Server API reference documentation is currently under development. + +## Overview + +The Computer Server provides WebSocket and REST API endpoints for remote computer control and automation. diff --git a/docs/content/docs/libraries/computer/index.mdx b/docs/content/docs/libraries/computer/index.mdx new file mode 100644 index 00000000..4ac698d6 --- /dev/null +++ b/docs/content/docs/libraries/computer/index.mdx @@ -0,0 +1,209 @@ +--- +title: Computer +description: Reference for the current version of the Computer library. +pypi: cua-computer +npm: '@trycua/computer' +github: + - https://github.com/trycua/cua/tree/main/libs/python/computer + - https://github.com/trycua/cua/tree/main/libs/typescript/computer +--- + +The Computer library provides a Computer class that can be used to control and automate a container running the Computer Server. + +## Reference + +### Basic Usage + +Connect to a cua cloud container: + + + + ```python + from computer import Computer + + computer = Computer( + os_type="linux", + provider_type="cloud", + name="your-container-name", + api_key="your-api-key" + ) + + computer = await computer.run() # Connect to a cua cloud container + ``` + + + + ```typescript + import { Computer, OSType } from '@trycua/computer'; + + const computer = new Computer({ + osType: OSType.LINUX, + name: "your-container-name", + apiKey: "your-api-key" + }); + + await computer.run(); // Connect to a cua cloud container + ``` + + + + +Connect to a cua local container: + + + + ```python + from computer import Computer + + computer = Computer( + os_type="macos" + ) + + computer = await computer.run() # Connect to the container + ``` + + + + +### Interface Actions + + + + ```python + # Shell Actions + result = await computer.interface.run_command(cmd) # Run shell command + # result.stdout, result.stderr, result.returncode + + # Mouse Actions + await computer.interface.left_click(x, y) # Left click at coordinates + await computer.interface.right_click(x, y) # Right click at coordinates + await computer.interface.double_click(x, y) # Double click at coordinates + await computer.interface.move_cursor(x, y) # Move cursor to coordinates + await computer.interface.drag_to(x, y, duration) # Drag to coordinates + await computer.interface.get_cursor_position() # Get current cursor position + await computer.interface.mouse_down(x, y, button="left") # Press and hold a mouse button + await computer.interface.mouse_up(x, y, button="left") # Release a mouse button + + # Keyboard Actions + await computer.interface.type_text("Hello") # Type text + await computer.interface.press_key("enter") # Press a single key + await computer.interface.hotkey("command", "c") # Press key combination + await computer.interface.key_down("command") # Press and hold a key + await computer.interface.key_up("command") # Release a key + + # Scrolling Actions + await computer.interface.scroll(x, y) # Scroll the mouse wheel + await computer.interface.scroll_down(clicks) # Scroll down + await computer.interface.scroll_up(clicks) # Scroll up + + # Screen Actions + await computer.interface.screenshot() # Take a screenshot + await computer.interface.get_screen_size() # Get screen dimensions + + # Clipboard Actions + await computer.interface.set_clipboard(text) # Set clipboard content + await computer.interface.copy_to_clipboard() # Get clipboard content + + # File System Operations + await computer.interface.file_exists(path) # Check if file exists + await computer.interface.directory_exists(path) # Check if directory exists + await computer.interface.read_text(path, encoding="utf-8") # Read file content + await computer.interface.write_text(path, content, encoding="utf-8") # Write file content + await computer.interface.read_bytes(path) # Read file content as bytes + await computer.interface.write_bytes(path, content) # Write file content as bytes + await computer.interface.delete_file(path) # Delete file + await computer.interface.create_dir(path) # Create directory + await computer.interface.delete_dir(path) # Delete directory + await computer.interface.list_dir(path) # List directory contents + + # Accessibility + await computer.interface.get_accessibility_tree() # Get accessibility tree + + # Delay Configuration + # Set default delay between all actions (in seconds) + computer.interface.delay = 0.5 # 500ms delay between actions + + # Or specify delay for individual actions + await computer.interface.left_click(x, y, delay=1.0) # 1 second delay after click + await computer.interface.type_text("Hello", delay=0.2) # 200ms delay after typing + await computer.interface.press_key("enter", delay=0.5) # 500ms delay after key press + + # Python Virtual Environment Operations + await computer.venv_install("demo_venv", ["requests", "macos-pyxa"]) # Install packages in a virtual environment + await computer.venv_cmd("demo_venv", "python -c 'import requests; print(requests.get(`https://httpbin.org/ip`).json())'') # Run a shell command in a virtual environment + await computer.venv_exec("demo_venv", python_function_or_code, *args, **kwargs) # Run a Python function in a virtual environment and return the result / raise an exception + + # Example: Use sandboxed functions to execute code in a Cua Container + from computer.helpers import sandboxed + + @sandboxed("demo_venv") + def greet_and_print(name): + """Get the HTML of the current Safari tab""" + import PyXA + safari = PyXA.Application("Safari") + html = safari.current_document.source() + print(f"Hello from inside the container, {name}!") + return {"greeted": name, "safari_html": html} + + # When a @sandboxed function is called, it will execute in the container + result = await greet_and_print("Cua") + # Result: {"greeted": "Cua", "safari_html": "..."} + # stdout and stderr are also captured and printed / raised + print("Result from sandboxed function:", result) + ``` + + + + ```typescript + // Shell Actions + const result = await computer.interface.runCommand(cmd); // Run shell command + // result.stdout, result.stderr, result.returncode + + // Mouse Actions + await computer.interface.leftClick(x, y); // Left click at coordinates + await computer.interface.rightClick(x, y); // Right click at coordinates + await computer.interface.doubleClick(x, y); // Double click at coordinates + await computer.interface.moveCursor(x, y); // Move cursor to coordinates + await computer.interface.dragTo(x, y, duration); // Drag to coordinates + await computer.interface.getCursorPosition(); // Get current cursor position + await computer.interface.mouseDown(x, y, "left"); // Press and hold a mouse button + await computer.interface.mouseUp(x, y, "left"); // Release a mouse button + + // Keyboard Actions + await computer.interface.typeText("Hello"); // Type text + await computer.interface.pressKey("enter"); // Press a single key + await computer.interface.hotkey("command", "c"); // Press key combination + await computer.interface.keyDown("command"); // Press and hold a key + await computer.interface.keyUp("command"); // Release a key + + // Scrolling Actions + await computer.interface.scroll(x, y); // Scroll the mouse wheel + await computer.interface.scrollDown(clicks); // Scroll down + await computer.interface.scrollUp(clicks); // Scroll up + + // Screen Actions + await computer.interface.screenshot(); // Take a screenshot + await computer.interface.getScreenSize(); // Get screen dimensions + + // Clipboard Actions + await computer.interface.setClipboard(text); // Set clipboard content + await computer.interface.copyToClipboard(); // Get clipboard content + + // File System Operations + await computer.interface.fileExists(path); // Check if file exists + await computer.interface.directoryExists(path); // Check if directory exists + await computer.interface.readText(path, "utf-8"); // Read file content + await computer.interface.writeText(path, content, "utf-8"); // Write file content + await computer.interface.readBytes(path); // Read file content as bytes + await computer.interface.writeBytes(path, content); // Write file content as bytes + await computer.interface.deleteFile(path); // Delete file + await computer.interface.createDir(path); // Create directory + await computer.interface.deleteDir(path); // Delete directory + await computer.interface.listDir(path); // List directory contents + + // Accessibility + await computer.interface.getAccessibilityTree(); // Get accessibility tree + ``` + + + diff --git a/docs/content/docs/libraries/core/index.mdx b/docs/content/docs/libraries/core/index.mdx new file mode 100644 index 00000000..394c7547 --- /dev/null +++ b/docs/content/docs/libraries/core/index.mdx @@ -0,0 +1,13 @@ +--- +title: Core +description: Reference for the current version of the Core library. +pypi: cua-core +npm: '@trycua/core' +github: + - https://github.com/trycua/cua/tree/main/libs/python/core + - https://github.com/trycua/cua/tree/main/libs/typescript/core +--- + +## Overview + +The Core library provides foundational utilities and shared functionality across the CUA ecosystem. diff --git a/docs/content/docs/libraries/lume/cli-reference.mdx b/docs/content/docs/libraries/lume/cli-reference.mdx new file mode 100644 index 00000000..da8bdee1 --- /dev/null +++ b/docs/content/docs/libraries/lume/cli-reference.mdx @@ -0,0 +1,71 @@ +--- +title: Lume CLI Reference +description: Command Line Interface reference for Lume +--- + +Lume is a lightweight Command Line Interface and local API server for creating, running and managing **macOS and Linux virtual machines** with near-native performance on Apple Silicon, using Apple's [Virtualization.Framework](https://developer.apple.com/documentation/virtualization). + +## Quick Start + +Install and run a prebuilt macOS VM in two commands: + +```bash +# Install Lume +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" +# Pull & start a macOS image +lume run macos-sequoia-vanilla:latest +``` + +> **Security Note**: All prebuilt images use the default password `lume`. Change this immediately after your first login using the `passwd` command. + +**System Requirements**: +- Apple Silicon Mac (M1, M2, M3, etc.) +- macOS 13.0 or later +- At least 8GB of RAM (16GB recommended) +- At least 50GB of free disk space + +## Install + +Install with a single command: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" +``` + +By default, Lume is installed as a background service that starts automatically on login. If you prefer to start the Lume API service manually when needed, you can use the `--no-background-service` option: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh) --no-background-service" +``` + +> **Note:** With this option, you'll need to manually start the Lume API service by running `lume serve` in your terminal whenever you need to use tools or libraries that rely on the Lume API (such as the Computer-Use Agent). + +You can also download the `lume.pkg.tar.gz` archive from the [latest release](https://github.com/trycua/cua/releases?q=lume&expanded=true), extract it, and install the package manually. + +## Using Lume + +Once installed, you can start using Lume with these common workflows: + +### Run a Prebuilt VM + +```bash +# Run a macOS Sequoia VM +lume run macos-sequoia-vanilla:latest + +# Run an Ubuntu VM +lume run ubuntu-noble-vanilla:latest +``` + +> We provide [prebuilt VM images](#prebuilt-images) in our [ghcr registry](https://github.com/orgs/trycua/packages). + +### Create a Custom VM + +```bash +# Create a new macOS VM +lume create my-macos-vm --cpu 4 --memory 8GB --disk-size 50GB + +# Create a Linux VM +lume create my-linux-vm --os linux --cpu 2 --memory 4GB +``` + +> **Disk Space**: The actual disk space used by sparse images will be much lower than the logical size listed. You can resize VM disks after creation using `lume set --disk-size `. diff --git a/docs/content/docs/libraries/lume/http-api.mdx b/docs/content/docs/libraries/lume/http-api.mdx new file mode 100644 index 00000000..5191119c --- /dev/null +++ b/docs/content/docs/libraries/lume/http-api.mdx @@ -0,0 +1,598 @@ +--- +title: HTTP Server API +description: Lume exposes a local HTTP API server that listens at localhost for programatic management of VMs. +--- + +import { Tabs, Tab } from 'fumadocs-ui/components/tabs'; + +## Default URL + +``` +http://localhost:7777 +``` + + + The HTTP API service runs on port `7777` by default. If you'd like to use a + different port, pass the `--port` option during installation or when running + `lume serve`. + + +## Endpoints + +### Create VM + +Create a new virtual machine. + +`POST: /vms` + +#### Parameters + +| Name | Type | Required | Description | +| -------- | ------- | -------- | ------------------------------------ | +| name | string | Yes | Name of the VM | +| os | string | Yes | Guest OS (`macOS`, `linux`, etc.) | +| cpu | integer | Yes | Number of CPU cores | +| memory | string | Yes | Memory size (e.g. `4GB`) | +| diskSize | string | Yes | Disk size (e.g. `64GB`) | +| display | string | No | Display resolution (e.g. `1024x768`) | +| ipsw | string | No | IPSW version (e.g. `latest`) | +| storage | string | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "name": "lume_vm", + "os": "macOS", + "cpu": 2, + "memory": "4GB", + "diskSize": "64GB", + "display": "1024x768", + "ipsw": "latest", + "storage": "ssd" + }' \ + http://localhost:7777/lume/vms +``` + + + + +```python +import requests + +payload = { + "name": "lume_vm", + "os": "macOS", + "cpu": 2, + "memory": "4GB", + "diskSize": "64GB", + "display": "1024x768", + "ipsw": "latest", + "storage": "ssd" +} +r = requests.post("http://localhost:7777/lume/vms", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + name: "lume_vm", + os: "macOS", + cpu: 2, + memory: "4GB", + diskSize: "64GB", + display: "1024x768", + ipsw: "latest", + storage: "ssd" +} + +const res = await fetch('http://localhost:7777/lume/vms', { + methdo: 'POST' + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()) +``` + + + + +### Run VM + +Run a virtual machine instance. + +`POST: /vms/:name/run` + +#### Parameters + +| Name | Type | Required | Description | +| ----------------- | --------------- | -------- | --------------------------------------------------- | +| noDisplay | boolean | No | If true, do not start VNC client | +| sharedDirectories | array of object | No | List of shared directories (`hostPath`, `readOnly`) | +| recoveryMode | boolean | No | Start in recovery mode | +| storage | string | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +# Basic run +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + http://localhost:7777/lume/vms/my-vm-name/run + +# Run with VNC client started and shared directory +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "noDisplay": false, + "sharedDirectories": [ + { + "hostPath": "~/Projects", + "readOnly": false + } + ], + "recoveryMode": false, + "storage": "ssd" + }' \ + http://localhost:7777/lume/vms/lume_vm/run +``` + + + + +```python +import requests + +# Basic run +r = requests.post("http://localhost:7777/lume/vms/my-vm-name/run", timeout=50) +print(r.json()) + +# With VNC and shared directory +payload = { + "noDisplay": False, + "sharedDirectories": [ + {"hostPath": "~/Projects", "readOnly": False} + ], + "recoveryMode": False, + "storage": "ssd" +} +r = requests.post("http://localhost:7777/lume/vms/lume_vm/run", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +// Basic run +const res = await fetch('http://localhost:7777/lume/vms/my-vm-name/run', { + method: 'POST', +}); +console.log(await res.json()); + +// With VNC and shared directory +const payload = { + noDisplay: false, + sharedDirectories: [{ hostPath: '~/Projects', readOnly: false }], + recoveryMode: false, + storage: 'ssd', +}; +const res2 = await fetch('http://localhost:7777/lume/vms/lume_vm/run', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res2.json()); +``` + + + + +### List VMs + +List all virtual machines. + +`GET: /vms` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/vms +``` + + + + +```python +import requests + +r = requests.get("http://localhost:7777/lume/vms", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/vms'); +console.log(await res.json()); +``` + + + + +```json +[ + { + "name": "my-vm", + "state": "stopped", + "os": "macOS", + "cpu": 2, + "memory": "4GB", + "diskSize": "64GB" + }, + { + "name": "my-vm-2", + "state": "stopped", + "os": "linux", + "cpu": 2, + "memory": "4GB", + "diskSize": "64GB" + } +] +``` + +### Get VM Details + +Get details for a specific virtual machine. + +`GET: /vms/:name` + +#### Parameters + +| Name | Type | Required | Description | +| ------- | ------ | -------- | -------------------------- | +| storage | string | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +# Basic get +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/vms/lume_vm + +# Get with specific storage +curl --connect-timeout 6000 \ + --max-time 5000 \ + http://localhost:7777/lume/vms/lume_vm?storage=ssd +``` + + + + +```python +import requests + +# Basic get +details = requests.get("http://localhost:7777/lume/vms/lume_vm", timeout=50) +print(details.json()) + +# Get with specific storage +details = requests.get("http://localhost:7777/lume/vms/lume_vm", params={"storage": "ssd"}, timeout=50) +print(details.json()) +``` + + + + +```typescript +// Basic get +const res = await fetch('http://localhost:7777/lume/vms/lume_vm'); +console.log(await res.json()); + +// Get with specific storage +const res2 = await fetch('http://localhost:7777/lume/vms/lume_vm?storage=ssd'); +console.log(await res2.json()); +``` + + + + +```json +{ + "name": "lume_vm", + "state": "stopped", + "os": "macOS", + "cpu": 2, + "memory": "4GB", + "diskSize": "64GB", + "display": "1024x768", + "ipAddress": "192.168.65.2", + "vncPort": 5900, + "sharedDirectories": [ + { + "hostPath": "~/Projects", + "readOnly": false, + "tag": "com.apple.virtio-fs.automount" + } + ] +} +``` + +### Update VM Configuration + +Update the configuration of a virtual machine. + +`PUT: /vms/:name` + +#### Parameters + +| Name | Type | Required | Description | +| -------- | ------- | -------- | ------------------------------------- | +| cpu | integer | No | Number of CPU cores | +| memory | string | No | Memory size (e.g. `8GB`) | +| diskSize | string | No | Disk size (e.g. `100GB`) | +| display | string | No | Display resolution (e.g. `1920x1080`) | +| storage | string | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X PUT \ + -H "Content-Type: application/json" \ + -d '{ + "cpu": 4, + "memory": "8GB", + "diskSize": "100GB", + "display": "1920x1080", + "storage": "ssd" + }' \ + http://localhost:7777/lume/vms/lume_vm +``` + + + + +```python +import requests + +payload = { + "cpu": 4, + "memory": "8GB", + "diskSize": "100GB", + "display": "1920x1080", + "storage": "ssd" +} +r = requests.put("http://localhost:7777/lume/vms/lume_vm", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + cpu: 4, + memory: '8GB', + diskSize: '100GB', + display: '1920x1080', + storage: 'ssd', +}; +const res = await fetch('http://localhost:7777/lume/vms/lume_vm', { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()); +``` + + + + +### Stop VM + +Stop a running virtual machine. + +`POST: /vms/:name/stop` + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + http://localhost:7777/lume/vms/lume_vm/stop +``` + + + + +```python +import requests + +r = requests.post("http://localhost:7777/lume/vms/lume_vm/stop", timeout=50) +print(r.json()) +``` + + + + +```typescript +const res = await fetch('http://localhost:7777/lume/vms/lume_vm/stop', { + method: 'POST', +}); +console.log(await res.json()); +``` + + + + +### Delete VM + +Delete a virtual machine instance. + +`DELETE: /vms/:name` + +#### Parameters + +| Name | Type | Required | Description | +| ------- | ------ | -------- | -------------------------- | +| storage | string | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +# Basic delete +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X DELETE \ + http://localhost:7777/lume/vms/lume_vm + +# Delete with specific storage +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X DELETE \ + http://localhost:7777/lume/vms/lume_vm?storage=ssd +``` + + + + +```python +import requests + +# Basic delete +r = requests.delete("http://localhost:7777/lume/vms/lume_vm", timeout=50) +print(r.status_code) + +# Delete with specific storage +r = requests.delete("http://localhost:7777/lume/vms/lume_vm", params={"storage": "ssd"}, timeout=50) +print(r.status_code) +``` + + + + +```typescript +// Basic delete +const res = await fetch('http://localhost:7777/lume/vms/lume_vm', { + method: 'DELETE', +}); +console.log(res.status); + +// Delete with specific storage +const res2 = await fetch('http://localhost:7777/lume/vms/lume_vm?storage=ssd', { + method: 'DELETE', +}); +console.log(res2.status); +``` + + + + +### Pull VM Image + +Pull a VM image from a registry. + +`POST: /images/pull` + +#### Parameters + +| Name | Type | Required | Description | +| ------------ | ------ | -------- | ------------------------------------- | +| image | string | Yes | Image name (e.g. `macos-sequoia-...`) | +| registry | string | Yes | Registry host (e.g. `ghcr.io`) | +| organization | string | Yes | Organization name | +| storage | string | No | Storage type (`ssd`, etc.) | + +#### Example Request + + + + +```bash +curl --connect-timeout 6000 \ + --max-time 5000 \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{ + "image": "macos-sequoia-vanilla:latest", + "registry": "ghcr.io", + "organization": "trycua", + "storage": "ssd" + }' \ + http://localhost:7777/lume/images/pull +``` + + + + +```python +import requests + +payload = { + "image": "macos-sequoia-vanilla:latest", + "registry": "ghcr.io", + "organization": "trycua", + "storage": "ssd" +} +r = requests.post("http://localhost:7777/lume/images/pull", json=payload, timeout=50) +print(r.json()) +``` + + + + +```typescript +const payload = { + image: 'macos-sequoia-vanilla:latest', + registry: 'ghcr.io', + organization: 'trycua', + storage: 'ssd', +}; +const res = await fetch('http://localhost:7777/lume/images/pull', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), +}); +console.log(await res.json()); +``` + + + diff --git a/docs/content/docs/libraries/lume/index.mdx b/docs/content/docs/libraries/lume/index.mdx new file mode 100644 index 00000000..28080bff --- /dev/null +++ b/docs/content/docs/libraries/lume/index.mdx @@ -0,0 +1,10 @@ +--- +title: Lume +description: Reference for the current version of the Lume CLI. +github: + - https://github.com/trycua/cua/tree/main/libs/lume +--- + +## Overview + +The Lume CLI provides command line tools for managing virtual machines with Lume. diff --git a/docs/content/docs/libraries/lumier/index.mdx b/docs/content/docs/libraries/lumier/index.mdx new file mode 100644 index 00000000..3858504d --- /dev/null +++ b/docs/content/docs/libraries/lumier/index.mdx @@ -0,0 +1,69 @@ +--- +title: Lumier +description: Reference for the current version of the Lumier library. +github: + - https://github.com/trycua/cua/tree/main/libs/lumier +--- + +## Overview + +The Lumier library provides a Docker-based interface for creating performant macOS virtual machines. + +## Installation + +**Requirements:** +- Docker for Apple Silicon (or compatible Mac) +- Lume virtualization CLI (install with: `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)"`) + +## Usage + +### Run a macOS VM (ephemeral) +```bash +docker run -it --rm \ + --name macos-vm \ + -p 8006:8006 \ + -e VM_NAME=macos-vm \ + -e VERSION=ghcr.io/trycua/macos-sequoia-cua:latest \ + -e CPU_CORES=4 \ + -e RAM_SIZE=8192 \ + trycua/lumier:latest +``` +Access the VM in your browser at [http://localhost:8006](http://localhost:8006). + +### Persistent Storage +```bash +mkdir -p storage + +docker run -it --rm \ + --name lumier-vm \ + -p 8006:8006 \ + -v $(pwd)/storage:/storage \ + -e VM_NAME=lumier-vm \ + -e VERSION=ghcr.io/trycua/macos-sequoia-cua:latest \ + -e CPU_CORES=4 \ + -e RAM_SIZE=8192 \ + -e HOST_STORAGE_PATH=$(pwd)/storage \ + trycua/lumier:latest +``` + +### Shared Folder +```bash +mkdir -p shared + +docker run -it --rm \ + --name lumier-vm \ + -p 8006:8006 \ + -v $(pwd)/storage:/storage \ + -v $(pwd)/shared:/shared \ + -e VM_NAME=lumier-vm \ + -e VERSION=ghcr.io/trycua/macos-sequoia-cua:latest \ + -e CPU_CORES=4 \ + -e RAM_SIZE=8192 \ + -e HOST_STORAGE_PATH=$(pwd)/storage \ + -e HOST_SHARED_PATH=$(pwd)/shared \ + trycua/lumier:latest +``` + +--- + +See the [Lumier README](https://github.com/trycua/cua/tree/main/libs/lumier) for advanced options, Docker Compose setup, and automation scripts. \ No newline at end of file diff --git a/docs/content/docs/libraries/mcp-server/index.mdx b/docs/content/docs/libraries/mcp-server/index.mdx new file mode 100644 index 00000000..f9885bf1 --- /dev/null +++ b/docs/content/docs/libraries/mcp-server/index.mdx @@ -0,0 +1,19 @@ +--- +title: MCP Server +description: Reference for the current version of the MCP Server library. +pypi: cua-mcp-server +github: + - https://github.com/trycua/cua/tree/main/libs/python/mcp-server +--- + +## ⚠️ 🚧 Under Construction 🚧 ⚠️ + +The MCP Server API reference documentation is currently under development. + +## Overview + +The MCP Server provides Model Context Protocol endpoints for AI model integration. + +## API Documentation + +Coming soon. diff --git a/docs/content/docs/libraries/som/index.mdx b/docs/content/docs/libraries/som/index.mdx new file mode 100644 index 00000000..e61f7a05 --- /dev/null +++ b/docs/content/docs/libraries/som/index.mdx @@ -0,0 +1,58 @@ +--- +title: Set-of-Mark +description: Reference for the current version of the Set-of-Mark library. +pypi: cua-som +github: + - https://github.com/trycua/cua/tree/main/libs/python/som +--- + +## Overview + +The SOM library provides visual element detection and interaction capabilities. It is based on the [Set-of-Mark](https://arxiv.org/abs/2310.11441) research paper and the [OmniParser](https://github.com/microsoft/OmniParser) model. + +## API Documentation + +### OmniParser Class + +```python +class OmniParser: + def __init__(self, device: str = "auto"): + """Initialize the parser with automatic device detection""" + + def parse( + self, + image: PIL.Image, + box_threshold: float = 0.3, + iou_threshold: float = 0.1, + use_ocr: bool = True, + ocr_engine: str = "easyocr" + ) -> ParseResult: + """Parse UI elements from an image""" +``` + +### ParseResult Object + +```python +@dataclass +class ParseResult: + elements: List[UIElement] # Detected elements + visualized_image: PIL.Image # Annotated image + processing_time: float # Time in seconds + + def to_dict(self) -> dict: + """Convert to JSON-serializable dictionary""" + + def filter_by_type(self, elem_type: str) -> List[UIElement]: + """Filter elements by type ('icon' or 'text')""" +``` + +### UIElement + +```python +class UIElement(BaseModel): + id: Optional[int] = Field(None) # Element ID (1-indexed) + type: Literal["icon", "text"] # Element type + bbox: BoundingBox # Bounding box coordinates { x1, y1, x2, y2 } + interactivity: bool = Field(default=False) # Whether the element is interactive + confidence: float = Field(default=1.0) # Detection confidence +``` diff --git a/docs/content/docs/meta.json b/docs/content/docs/meta.json new file mode 100644 index 00000000..9aea034a --- /dev/null +++ b/docs/content/docs/meta.json @@ -0,0 +1,19 @@ +{ + "title": "Home", + "description": "Documentation Home", + "root": true, + "defaultOpen": true, + "pages": [ + "index", + "quickstart-ui", + "quickstart-cli", + "quickstart-devs", + "telemetry", + "---[BookCopy]Computer Playbook---", + "...computer-sdk", + "---[BookCopy]Agent Playbook---", + "...agent-sdk", + "---[CodeXml]API Reference---", + "...libraries" + ] +} \ No newline at end of file diff --git a/docs/content/docs/quickstart-cli.mdx b/docs/content/docs/quickstart-cli.mdx new file mode 100644 index 00000000..84aa80ae --- /dev/null +++ b/docs/content/docs/quickstart-cli.mdx @@ -0,0 +1,281 @@ +--- +title: Quickstart (CLI) +description: Get started with the cua Agent CLI in 4 steps +icon: Rocket +--- + +import { Step, Steps } from 'fumadocs-ui/components/steps'; +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; +import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; + +Get up and running with the cua Agent CLI in 4 simple steps. + + + + +## Introduction + +cua combines Computer (interface) + Agent (AI) for automating desktop apps. The Agent CLI provides a clean terminal interface to control your remote computer using natural language commands. + + + + + +## Create Your First cua Container + +1. Go to [trycua.com/signin](https://www.trycua.com/signin) +2. Navigate to **Dashboard > Containers > Create Instance** +3. Create a **Medium, Ubuntu 22** container +4. Note your container name and API key + + + + + +## Install cua + + + + + +### Install uv + + + + +```bash +# Use curl to download the script and execute it with sh: +curl -LsSf https://astral.sh/uv/install.sh | sh + +# If your system doesn't have curl, you can use wget: +# wget -qO- https://astral.sh/uv/install.sh | sh +``` + + + + +```powershell +# Use irm to download the script and execute it with iex: +powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" +``` + + + + +### Install Python 3.12 + +```bash +uv python install 3.12 +# uv will install cua dependencies automatically when you use --with "cua-agent[cli]" +``` + + + + + +### Install conda + + + + +```bash +mkdir -p ~/miniconda3 +curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o ~/miniconda3/miniconda.sh +bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 +rm ~/miniconda3/miniconda.sh +source ~/miniconda3/bin/activate +``` + + + + +```bash +mkdir -p ~/miniconda3 +wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh +bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 +rm ~/miniconda3/miniconda.sh +source ~/miniconda3/bin/activate +``` + + + + +```powershell +wget "https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe" -outfile ".\miniconda.exe" +Start-Process -FilePath ".\miniconda.exe" -ArgumentList "/S" -Wait +del .\miniconda.exe +``` + + + + +### Create and activate Python 3.12 environment + +```bash +conda create -n cua python=3.12 +conda activate cua +``` + +### Install cua + +```bash +pip install "cua-agent[cli]" cua-computer +``` + + + + + +### Install cua + +```bash +pip install "cua-agent[cli]" cua-computer +``` + + + + + + + + + +## Run cua CLI + +Choose your preferred AI model: + +### OpenAI Computer Use Preview + + + + +```bash +uv run --with "cua-agent[cli]" -m agent.cli openai/computer-use-preview +``` + + + + +```bash +python -m agent.cli openai/computer-use-preview +``` + + + + +### Anthropic Claude + + + + +```bash +uv run --with "cua-agent[cli]" -m agent.cli anthropic/claude-3-5-sonnet-20241022 +uv run --with "cua-agent[cli]" -m agent.cli anthropic/claude-opus-4-20250514 +uv run --with "cua-agent[cli]" -m agent.cli anthropic/claude-sonnet-4-20250514 +``` + + + + +```bash +python -m agent.cli anthropic/claude-3-5-sonnet-20241022 +python -m agent.cli anthropic/claude-opus-4-20250514 +python -m agent.cli anthropic/claude-sonnet-4-20250514 +``` + + + + +### Omniparser + LLMs + + + + +```bash +uv run --with "cua-agent[cli]" -m agent.cli omniparser+anthropic/claude-3-5-sonnet-20241022 +uv run --with "cua-agent[cli]" -m agent.cli omniparser+openai/gpt-4o +uv run --with "cua-agent[cli]" -m agent.cli omniparser+vertex_ai/gemini-pro +``` + + + + +```bash +python -m agent.cli omniparser+anthropic/claude-3-5-sonnet-20241022 +python -m agent.cli omniparser+openai/gpt-4o +python -m agent.cli omniparser+vertex_ai/gemini-pro +``` + + + + +### Local Models + + + + +```bash +# Hugging Face models (local) +uv run --with "cua-agent[cli]" -m agent.cli huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B + +# MLX models (Apple Silicon) +uv run --with "cua-agent[cli]" -m agent.cli mlx/mlx-community/UI-TARS-1.5-7B-6bit + +# Ollama models +uv run --with "cua-agent[cli]" -m agent.cli omniparser+ollama_chat/llama3.2:latest +``` + + + + +```bash +# Hugging Face models (local) +python -m agent.cli huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B + +# MLX models (Apple Silicon) +python -m agent.cli mlx/mlx-community/UI-TARS-1.5-7B-6bit + +# Ollama models +python -m agent.cli omniparser+ollama_chat/llama3.2:latest +``` + + + + +### Interactive Setup + +If you haven't set up environment variables, the CLI will guide you through the setup: + +1. **Container Name**: Enter your cua container name (or get one at [trycua.com](https://www.trycua.com/)) +2. **CUA API Key**: Enter your cua API key +3. **Provider API Key**: Enter your AI provider API key (OpenAI, Anthropic, etc.) + +### Start Chatting + +Once connected, you'll see: + +``` +💻 Connected to your-container-name (model, agent_loop) +Type 'exit' to quit. + +> +``` + +You can ask your agent to perform actions like: + +- "Take a screenshot and tell me what's on the screen" +- "Open Firefox and go to github.com" +- "Type 'Hello world' into the terminal" +- "Close the current window" +- "Click on the search button" + + + + +--- + +For advanced Python usage and GUI interface, see the [Quickstart (GUI)](/quickstart-ui) and [Quickstart for Developers](/quickstart-devs). + +For a complete list of supported models, see [Supported Agents](/agent-sdk/supported-agents). + +For running models locally, see [Running Models Locally](/agent-sdk/local-models). diff --git a/docs/content/docs/quickstart-devs.mdx b/docs/content/docs/quickstart-devs.mdx new file mode 100644 index 00000000..cd002746 --- /dev/null +++ b/docs/content/docs/quickstart-devs.mdx @@ -0,0 +1,127 @@ +--- +title: Quickstart (for Developers) +description: Get started with cua in 5 steps +icon: Rocket +--- + +import { Step, Steps } from 'fumadocs-ui/components/steps'; +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; + +Get up and running with cua in 5 simple steps. + + + + +## Introduction + +cua combines Computer (interface) + Agent (AI) for automating desktop apps. Computer handles clicks/typing, Agent provides the intelligence. + + + + + +## Create Your First cua Container + +1. Go to [trycua.com/signin](https://www.trycua.com/signin) +2. Navigate to **Dashboard > Containers > Create Instance** +3. Create a **Medium, Ubuntu 22** container +4. Note your container name and API key + + + + + +## Install cua + + + + ```bash pip install "cua-agent[all]" cua-computer ``` + + ```bash npm install @trycua/computer ``` + + + + + + +## Using Computer + + + + ```python + from computer import Computer + + async with Computer( + os_type="linux", + provider_type="cloud", + name="your-container-name", + api_key="your-api-key" + ) as computer: + # Take screenshot + screenshot = await computer.interface.screenshot() + + # Click and type + await computer.interface.left_click(100, 100) + await computer.interface.type("Hello!") + ``` + + + + ```typescript + import { Computer, OSType } from '@trycua/computer'; + + const computer = new Computer({ + osType: OSType.LINUX, + name: "your-container-name", + apiKey: "your-api-key" + }); + + await computer.run(); + + try { + // Take screenshot + const screenshot = await computer.interface.screenshot(); + + // Click and type + await computer.interface.leftClick(100, 100); + await computer.interface.typeText("Hello!"); + } finally { + await computer.close(); + } + ``` + + + + + + + + +## Using Agent + +```python +from agent import ComputerAgent + +agent = ComputerAgent( + model="anthropic/claude-3-5-sonnet-20241022", + tools=[computer], + max_trajectory_budget=5.0 +) + +messages = [{"role": "user", "content": "Take a screenshot and tell me what you see"}] + +async for result in agent.run(messages): + for item in result["output"]: + if item["type"] == "message": + print(item["content"][0]["text"]) +``` + + + + +## Next Steps + +{/* - Explore the [SDK documentation](/sdk) for advanced features */} + +- Learn about [trajectory tracking](/agent-sdk/callbacks/trajectories) and [callbacks](/agent-sdk/callbacks/agent-lifecycle) +- Join our [Discord community](https://discord.com/invite/mVnXXpdE85) for support diff --git a/docs/content/docs/quickstart-ui.mdx b/docs/content/docs/quickstart-ui.mdx new file mode 100644 index 00000000..fb7a2b0d --- /dev/null +++ b/docs/content/docs/quickstart-ui.mdx @@ -0,0 +1,166 @@ +--- +title: Quickstart (GUI) +description: Get started with the cua Agent UI in 3 steps +icon: Rocket +--- + +import { Step, Steps } from 'fumadocs-ui/components/steps'; +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; +import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; + +Get up and running with the cua Agent UI in 3 simple steps. + + + + +## Introduction + +cua combines Computer (interface) + Agent (AI) for automating desktop apps. The Agent UI provides a simple chat interface to control your remote computer using natural language. + + + + + +## Create Your First cua Container + +1. Go to [trycua.com/signin](https://www.trycua.com/signin) +2. Navigate to **Dashboard > Containers > Create Instance** +3. Create a **Medium, Ubuntu 22** container +4. Note your container name and API key + + + + + +## Install and Run cua + + + + + +### Install uv + + + + +```bash +# Use curl to download the script and execute it with sh: +curl -LsSf https://astral.sh/uv/install.sh | sh + +# If your system doesn't have curl, you can use wget: +# wget -qO- https://astral.sh/uv/install.sh | sh +``` + + + + +```powershell +# Use irm to download the script and execute it with iex: +powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" +``` + + + + +### Install Python 3.12 + +```bash +uv python install 3.12 +``` + +### Run cua + +```bash +uv run --with "cua-agent[ui]" -m agent.ui +``` + + + + + +### Install conda + + + + +```bash +mkdir -p ~/miniconda3 +curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o ~/miniconda3/miniconda.sh +bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 +rm ~/miniconda3/miniconda.sh +source ~/miniconda3/bin/activate +``` + + + + +```bash +mkdir -p ~/miniconda3 +wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh +bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 +rm ~/miniconda3/miniconda.sh +source ~/miniconda3/bin/activate +``` + + + + +```powershell +wget "https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe" -outfile ".\miniconda.exe" +Start-Process -FilePath ".\miniconda.exe" -ArgumentList "/S" -Wait +del .\miniconda.exe +``` + + + + +### Create and activate Python 3.12 environment + +```bash +conda create -n cua python=3.12 +conda activate cua +``` + +### Install and run cua + +```bash +pip install "cua-agent[ui]" cua-computer +python -m agent.ui +``` + + + + + +### Install cua + +```bash +pip install "cua-agent[ui]" cua-computer +``` + +### Run the Agent UI + +```bash +python -m agent.ui +``` + + + + + +### Start Chatting + +Open your browser to the displayed URL and start chatting with your computer-using agent. + +You can ask your agent to perform actions like: + +- "Open Firefox and go to github.com" +- "Take a screenshot and tell me what's on the screen" +- "Type 'Hello world' into the terminal" + + + + +--- + +For advanced Python usage, see the [Quickstart for Developers](/quickstart-devs). diff --git a/docs/content/docs/telemetry.mdx b/docs/content/docs/telemetry.mdx new file mode 100644 index 00000000..a62b4f5f --- /dev/null +++ b/docs/content/docs/telemetry.mdx @@ -0,0 +1,144 @@ +--- +title: Telemetry +description: This document explains how telemetry works in CUA libraries and how you can control it. +icon: RadioTower +--- + +# Telemetry in CUA + +CUA tracks anonymized usage and error report statistics; we ascribe to Posthog's approach as detailed [here](https://posthog.com/blog/open-source-telemetry-ethical). If you would like to opt out of sending anonymized info, you can set `telemetry_enabled` to false. + +## What telemetry data we collect + +CUA libraries collect usage data to help improve our software. We have two categories of telemetry: + +### Opt-Out Telemetry (Enabled by Default) + +Basic performance metrics and system information that help us understand usage patterns: + +- **System Information**: Operating system, OS version, Python version +- **Module Initialization**: When modules are imported and their versions +- **Performance Metrics**: Agent run durations, step counts, token usage, and API costs +- **Session Tracking**: Anonymous session IDs and run IDs for performance analysis + +### Opt-In Telemetry (Disabled by Default) + +**Conversation Trajectory Logging**: Full conversation history including: +- User messages and agent responses +- Computer actions and their outputs +- Reasoning traces from the agent + +**Important**: Trajectory logging is **opt-in only** and must be explicitly enabled. + +### We do NOT collect: + +- Personal information or user identifiers +- API keys or credentials +- File contents or application data +- Information about files being accessed +- Actual screenshots or screen contents (unless trajectory logging is enabled) +- Specific text being typed, including user inputs, model outputs, computer outputs, or tool call outputs (unless trajectory logging is enabled) + +## Controlling Telemetry + +We are committed to transparency and user control over telemetry. There are two ways to control telemetry: + +### 1. Environment Variable (Global Control) + +Telemetry is enabled by default. To disable telemetry, set the `CUA_TELEMETRY_ENABLED` environment variable to a falsy value (`0`, `false`, `no`, or `off`): + +```bash +# Disable telemetry before running your script +export CUA_TELEMETRY_ENABLED=false + +# Or as part of the command +CUA_TELEMETRY_ENABLED=1 python your_script.py + +``` + +Or from Python: + +```python +import os +os.environ["CUA_TELEMETRY_ENABLED"] = "false" +``` + +### 2. Instance-Level Control + +#### Computer SDK + +```python +from computer import Computer + +# Enable telemetry (default) +computer = Computer(telemetry_enabled=True) + +# Disable telemetry +computer = Computer(telemetry_enabled=False) +``` + +#### Agent SDK + +```python +from agent import ComputerAgent +import os + +# Basic telemetry - performance metrics only (opt-out, enabled by default) +agent = ComputerAgent( + model="claude-3-5-sonnet-20241022", + telemetry_enabled=True # Default is True +) + +# Enable telemetry with full conversation trajectory logging (opt-in) +agent = ComputerAgent( + model="claude-3-5-sonnet-20241022", + telemetry_enabled={ + "log_trajectory": True # Logs full conversation items + } +) + +# Disable telemetry completely +agent = ComputerAgent( + model="claude-3-5-sonnet-20241022", + telemetry_enabled=False +) + +# Disable telemetry completely using environment variables +os.environ["CUA_TELEMETRY_ENABLED"] = "false" +agent = ComputerAgent( + model="claude-3-5-sonnet-20241022" +) +``` + +You can check if telemetry is enabled for an instance: + +```python +print(computer.telemetry_enabled) # Will print True or False +print(agent.telemetry_enabled) # Will print True, False, or dict +``` + +Note that telemetry settings must be configured during initialization and cannot be changed after the object is created. + +## Detailed Telemetry Events + +### Computer SDK Events + +| Event Name | Data Collected | Trigger Notes | +|------------|----------------|---------------| +| **computer_initialized** | • `os`: Operating system (e.g., 'windows', 'darwin', 'linux')
• `os_version`: OS version
• `python_version`: Python version | Triggered when a Computer instance is created | +| **module_init** | • `module`: "computer"
• `version`: Package version
• `python_version`: Full Python version string | Triggered once when the computer package is imported for the first time | + +### Agent SDK Events + +| Event Name | Data Collected | Trigger Notes | +|------------|----------------|---------------| +| **module_init** | • `module`: "agent"
• `version`: Package version
• `python_version`: Full Python version string | Triggered once when the agent package is imported for the first time | +| **agent_session_start** | • `session_id`: Unique UUID for this agent instance
• `agent_type`: Class name (e.g., "ComputerAgent")
• `model`: Model name (e.g., "claude-3-5-sonnet")
• `os`: Operating system
• `os_version`: OS version
• `python_version`: Python version | Triggered when TelemetryCallback is initialized (agent instantiation) | +| **agent_run_start** | • `session_id`: Agent session UUID
• `run_id`: Unique UUID for this run
• `start_time`: Unix timestamp
• `input_context_size`: Character count of input messages
• `num_existing_messages`: Count of existing messages
• `uploaded_trajectory`: Full conversation items (opt-in) | Triggered at the start of each agent.run() call | +| **agent_run_end** | • `session_id`: Agent session UUID
• `run_id`: Run UUID
• `end_time`: Unix timestamp
• `duration_seconds`: Total run duration
• `num_steps`: Total steps taken in this run
• `total_usage`: Accumulated token usage and costs
• `uploaded_trajectory`: Full conversation items (opt-in) | Triggered at the end of each agent.run() call | +| **agent_step** | • `session_id`: Agent session UUID
• `run_id`: Run UUID
• `step`: Step number (incremental)
• `timestamp`: Unix timestamp
• `duration_seconds`: Duration of previous step | Triggered on each agent response/step during a run | +| **agent_usage** | • `session_id`: Agent session UUID
• `run_id`: Run UUID
• `step`: Current step number
• `prompt_tokens`: Tokens in prompt
• `completion_tokens`: Tokens in response
• `total_tokens`: Total tokens used
• `response_cost`: Cost of this API call | Triggered whenever usage information is received from LLM API | + +## Transparency + +We believe in being transparent about the data we collect. If you have any questions about our telemetry practices, please open an issue on our GitHub repository. diff --git a/docs/next.config.mjs b/docs/next.config.mjs new file mode 100644 index 00000000..472674c4 --- /dev/null +++ b/docs/next.config.mjs @@ -0,0 +1,48 @@ +import { createMDX } from 'fumadocs-mdx/next'; + +const withMDX = createMDX(); + +/** @type {import('next').NextConfig} */ +const config = { + reactStrictMode: true, + trailingSlash: false, + basePath: '/docs', + assetPrefix: '/docs', + async rewrites() { + return [ + { + source: '/:path*.mdx', + destination: '/llms.mdx/:path*', + }, + ]; + }, + async redirects() { + return [ + { + source: '/', + destination: '/docs', + basePath: false, // Important: this bypasses the basePath + permanent: false, + }, + ]; + }, + images: { + dangerouslyAllowSVG: true, + remotePatterns: [ + { + protocol: 'https', + hostname: 'img.shields.io', + }, + { + protocol: 'https', + hostname: 'starchart.cc', + }, + { + protocol: 'https', + hostname: 'github.com', + }, + ], + }, +}; + +export default withMDX(config); diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..c6c083c9 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,45 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "dev": "next dev --turbo -p 8090", + "start": "next start -p 8090", + "postinstall": "fumadocs-mdx" + }, + "dependencies": { + "fumadocs-core": "15.5.1", + "fumadocs-mdx": "11.6.7", + "fumadocs-ui": "15.5.1", + "lucide-react": "^0.525.0", + "mermaid": "^11.8.1", + "next": "15.3.3", + "next-themes": "^0.4.6", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "remark": "^15.0.1", + "remark-gfm": "^4.0.1", + "remark-mdx": "^3.1.0", + "tailwind-merge": "^3.3.1", + "zod": "^3.25.76" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.8", + "@types/mdx": "^2.0.13", + "@types/node": "22.15.28", + "@types/react": "^19.1.6", + "@types/react-dom": "^19.1.5", + "postcss": "^8.5.4", + "prettier": "^3.6.2", + "tailwindcss": "^4.1.8", + "typescript": "^5.8.3" + }, + "pnpm": { + "onlyBuiltDependencies": [ + "@tailwindcss/oxide", + "esbuild", + "sharp" + ] + } +} \ No newline at end of file diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 00000000..21945e6b --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,4941 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + fumadocs-core: + specifier: 15.5.1 + version: 15.5.1(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + fumadocs-mdx: + specifier: 11.6.7 + version: 11.6.7(acorn@8.15.0)(fumadocs-core@15.5.1(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + fumadocs-ui: + specifier: 15.5.1 + version: 15.5.1(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.1.10) + lucide-react: + specifier: ^0.525.0 + version: 0.525.0(react@19.1.0) + mermaid: + specifier: ^11.8.1 + version: 11.8.1 + next: + specifier: 15.3.3 + version: 15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + remark: + specifier: ^15.0.1 + version: 15.0.1 + remark-gfm: + specifier: ^4.0.1 + version: 4.0.1 + remark-mdx: + specifier: ^3.1.0 + version: 3.1.0 + tailwind-merge: + specifier: ^3.3.1 + version: 3.3.1 + zod: + specifier: ^3.25.76 + version: 3.25.76 + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.8 + version: 4.1.10 + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 + '@types/node': + specifier: 22.15.28 + version: 22.15.28 + '@types/react': + specifier: ^19.1.6 + version: 19.1.8 + '@types/react-dom': + specifier: ^19.1.5 + version: 19.1.6(@types/react@19.1.8) + postcss: + specifier: ^8.5.4 + version: 8.5.6 + prettier: + specifier: ^3.6.2 + version: 3.6.2 + tailwindcss: + specifier: ^4.1.8 + version: 4.1.10 + typescript: + specifier: ^5.8.3 + version: 5.8.3 + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@antfu/utils@8.1.1': + resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} + + '@braintree/sanitize-url@7.1.1': + resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + + '@chevrotain/cst-dts-gen@11.0.3': + resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} + + '@chevrotain/gast@11.0.3': + resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} + + '@chevrotain/regexp-to-ast@11.0.3': + resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} + + '@chevrotain/types@11.0.3': + resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} + + '@chevrotain/utils@11.0.3': + resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@floating-ui/core@1.7.1': + resolution: {integrity: sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==} + + '@floating-ui/dom@1.7.1': + resolution: {integrity: sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==} + + '@floating-ui/react-dom@2.1.3': + resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@formatjs/intl-localematcher@0.6.1': + resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.3.0': + resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} + + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@mdx-js/mdx@3.1.0': + resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} + + '@mermaid-js/parser@0.6.1': + resolution: {integrity: sha512-lCQNpV8R4lgsGcjX5667UiuDLk2micCtjtxR1YKbBXvN5w2v+FeLYoHrTSSrjwXdMcDYvE4ZBPvKT31dfeSmmA==} + + '@next/env@15.3.3': + resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==} + + '@next/swc-darwin-arm64@15.3.3': + resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.3.3': + resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.3.3': + resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.3.3': + resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.3.3': + resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.3.3': + resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.3.3': + resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.3.3': + resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@orama/orama@3.1.7': + resolution: {integrity: sha512-6yB0117ZjsgNevZw3LP+bkrZa9mU/POPVaXgzMPOBbBc35w2P3R+1vMMhEfC06kYCpd5bf0jodBaTkYQW5TVeQ==} + engines: {node: '>= 20.0.0'} + + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.2': + resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + + '@radix-ui/react-accordion@1.2.11': + resolution: {integrity: sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.11': + resolution: {integrity: sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.14': + resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.10': + resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.2': + resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-navigation-menu@1.2.13': + resolution: {integrity: sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.14': + resolution: {integrity: sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.7': + resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.4': + resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.10': + resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.9': + resolution: {integrity: sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tabs@1.1.12': + resolution: {integrity: sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@shikijs/core@3.7.0': + resolution: {integrity: sha512-yilc0S9HvTPyahHpcum8eonYrQtmGTU0lbtwxhA6jHv4Bm1cAdlPFRCJX4AHebkCm75aKTjjRAW+DezqD1b/cg==} + + '@shikijs/engine-javascript@3.7.0': + resolution: {integrity: sha512-0t17s03Cbv+ZcUvv+y33GtX75WBLQELgNdVghnsdhTgU3hVcWcMsoP6Lb0nDTl95ZJfbP1mVMO0p3byVh3uuzA==} + + '@shikijs/engine-oniguruma@3.7.0': + resolution: {integrity: sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw==} + + '@shikijs/langs@3.7.0': + resolution: {integrity: sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ==} + + '@shikijs/rehype@3.7.0': + resolution: {integrity: sha512-YjAZxhQnBXE8ehppKGzuVGPoE4pjVsxqzkWhBZlkP495AjlR++MgfiRFcQfDt3qX5lK3gEDTcghB/8E3yNrWqQ==} + + '@shikijs/themes@3.7.0': + resolution: {integrity: sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ==} + + '@shikijs/transformers@3.7.0': + resolution: {integrity: sha512-VplaqIMRNsNOorCXJHkbF5S0pT6xm8Z/s7w7OPZLohf8tR93XH0krvUafpNy/ozEylrWuShJF0+ftEB+wFRwGA==} + + '@shikijs/types@3.7.0': + resolution: {integrity: sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tailwindcss/node@4.1.10': + resolution: {integrity: sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==} + + '@tailwindcss/oxide-android-arm64@4.1.10': + resolution: {integrity: sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.10': + resolution: {integrity: sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.10': + resolution: {integrity: sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.10': + resolution: {integrity: sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10': + resolution: {integrity: sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.10': + resolution: {integrity: sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.10': + resolution: {integrity: sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.10': + resolution: {integrity: sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.10': + resolution: {integrity: sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.10': + resolution: {integrity: sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.10': + resolution: {integrity: sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.10': + resolution: {integrity: sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.10': + resolution: {integrity: sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.10': + resolution: {integrity: sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==} + + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.6': + resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@22.15.28': + resolution: {integrity: sha512-I0okKVDmyKR281I0UIFV7EWAWRnR0gkuSKob5wVcByyyhr7Px/slhkQapcYX4u00ekzNWaS1gznKZnuzxwo4pw==} + + '@types/react-dom@19.1.6': + resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} + peerDependencies: + '@types/react': ^19.0.0 + + '@types/react@19.1.8': + resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + caniuse-lite@1.0.30001724: + resolution: {integrity: sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.0.3: + resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.32.1: + resolution: {integrity: sha512-dbeqFTLYEwlFg7UGtcZhCCG/2WayX72zK3Sq323CEX29CY81tYfVhw1MIdduCtpstB0cTOhJswWlM/OEB3Xp+Q==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.11: + resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dompurify@3.2.6: + resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.4.0: + resolution: {integrity: sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + exsolve@1.0.7: + resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fumadocs-core@15.5.1: + resolution: {integrity: sha512-5eJPJw+BFWFdgrtWPQ9aAZAhhsyuZAwth8OjBd9R77sXoIoae4Y4lJZMq3BeSpJZcuIAOVbSCS+pJhsBAoXJ8g==} + peerDependencies: + '@oramacloud/client': 1.x.x || 2.x.x + algoliasearch: 5.x.x + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + peerDependenciesMeta: + '@oramacloud/client': + optional: true + algoliasearch: + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + + fumadocs-mdx@11.6.7: + resolution: {integrity: sha512-jOZzxowvhwe9RzV6jVjIS2FsQIz9P6QYkMBPgR0nq9+7trP+mmiLoIq5EwhTPrR/Y/4gTiSl9TXFWxTY02trnw==} + hasBin: true + peerDependencies: + '@fumadocs/mdx-remote': ^1.2.0 + fumadocs-core: ^14.0.0 || ^15.0.0 + next: ^15.3.0 + peerDependenciesMeta: + '@fumadocs/mdx-remote': + optional: true + + fumadocs-ui@15.5.1: + resolution: {integrity: sha512-HyMoM+mv5WZrXDAv88SLLqFrduDSxQHFU+uQkSpJQdycaGNSIB8063PW/wb/QIliusWP8o+c/YLFy/29KymEWA==} + peerDependencies: + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + tailwindcss: ^3.4.14 || ^4.0.0 + peerDependenciesMeta: + tailwindcss: + optional: true + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + katex@0.16.22: + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} + hasBin: true + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + langium@3.3.1: + resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} + engines: {node: '>=16.0.0'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + + local-pkg@1.1.1: + resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + engines: {node: '>=14'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + lru-cache@11.1.0: + resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + engines: {node: 20 || >=22} + + lucide-react@0.525.0: + resolution: {integrity: sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@15.0.12: + resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} + engines: {node: '>= 18'} + hasBin: true + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mermaid@11.8.1: + resolution: {integrity: sha512-VSXJLqP1Sqw5sGr273mhvpPRhXwE6NlmMSqBZQw+yZJoAJkOIPPn/uT3teeCBx60Fkt5zEI3FrH2eVT0jXRDzw==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + next@15.3.3: + resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.3: + resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} + + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.2.0: + resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + engines: {node: '>=4'} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 + + react-medium-image-zoom@5.2.14: + resolution: {integrity: sha512-nfTVYcAUnBzXQpPDcZL+cG/e6UceYUIG+zDcnemL7jtAqbJjVVkA85RgneGtJeni12dTyiRPZVM6Szkmwd/o8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.1: + resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.0: + resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==} + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.0: + resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shiki@3.7.0: + resolution: {integrity: sha512-ZcI4UT9n6N2pDuM2n3Jbk0sR4Swzq43nLPgS/4h0E3B/NrFn2HKElrDtceSf8Zx/OWYOo7G1SAtBLypCp+YXqg==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + style-to-js@1.1.17: + resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==} + + style-to-object@1.0.9: + resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + + tailwindcss@4.1.10: + resolution: {integrity: sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==} + + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} + engines: {node: '>=6'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + engines: {node: '>=12.0.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.3.0 + tinyexec: 1.0.1 + + '@antfu/utils@8.1.1': {} + + '@braintree/sanitize-url@7.1.1': {} + + '@chevrotain/cst-dts-gen@11.0.3': + dependencies: + '@chevrotain/gast': 11.0.3 + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/gast@11.0.3': + dependencies: + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/regexp-to-ast@11.0.3': {} + + '@chevrotain/types@11.0.3': {} + + '@chevrotain/utils@11.0.3': {} + + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.5': + optional: true + + '@esbuild/android-arm64@0.25.5': + optional: true + + '@esbuild/android-arm@0.25.5': + optional: true + + '@esbuild/android-x64@0.25.5': + optional: true + + '@esbuild/darwin-arm64@0.25.5': + optional: true + + '@esbuild/darwin-x64@0.25.5': + optional: true + + '@esbuild/freebsd-arm64@0.25.5': + optional: true + + '@esbuild/freebsd-x64@0.25.5': + optional: true + + '@esbuild/linux-arm64@0.25.5': + optional: true + + '@esbuild/linux-arm@0.25.5': + optional: true + + '@esbuild/linux-ia32@0.25.5': + optional: true + + '@esbuild/linux-loong64@0.25.5': + optional: true + + '@esbuild/linux-mips64el@0.25.5': + optional: true + + '@esbuild/linux-ppc64@0.25.5': + optional: true + + '@esbuild/linux-riscv64@0.25.5': + optional: true + + '@esbuild/linux-s390x@0.25.5': + optional: true + + '@esbuild/linux-x64@0.25.5': + optional: true + + '@esbuild/netbsd-arm64@0.25.5': + optional: true + + '@esbuild/netbsd-x64@0.25.5': + optional: true + + '@esbuild/openbsd-arm64@0.25.5': + optional: true + + '@esbuild/openbsd-x64@0.25.5': + optional: true + + '@esbuild/sunos-x64@0.25.5': + optional: true + + '@esbuild/win32-arm64@0.25.5': + optional: true + + '@esbuild/win32-ia32@0.25.5': + optional: true + + '@esbuild/win32-x64@0.25.5': + optional: true + + '@floating-ui/core@1.7.1': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.7.1': + dependencies: + '@floating-ui/core': 1.7.1 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/react-dom@2.1.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/dom': 1.7.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + '@floating-ui/utils@0.2.9': {} + + '@formatjs/intl-localematcher@0.6.1': + dependencies: + tslib: 2.8.1 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.3.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@antfu/utils': 8.1.1 + '@iconify/types': 2.0.0 + debug: 4.4.1 + globals: 15.15.0 + kolorist: 1.8.0 + local-pkg: 1.1.1 + mlly: 1.7.4 + transitivePeerDependencies: + - supports-color + + '@img/sharp-darwin-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + optional: true + + '@img/sharp-darwin-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + + '@img/sharp-linux-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + + '@img/sharp-linux-arm@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + + '@img/sharp-linux-s390x@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + + '@img/sharp-linux-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + + '@img/sharp-wasm32@0.34.2': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + + '@img/sharp-win32-arm64@0.34.2': + optional: true + + '@img/sharp-win32-ia32@0.34.2': + optional: true + + '@img/sharp-win32-x64@0.34.2': + optional: true + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@mdx-js/mdx@3.1.0(acorn@8.15.0)': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.0(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.4 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - acorn + - supports-color + + '@mermaid-js/parser@0.6.1': + dependencies: + langium: 3.3.1 + + '@next/env@15.3.3': {} + + '@next/swc-darwin-arm64@15.3.3': + optional: true + + '@next/swc-darwin-x64@15.3.3': + optional: true + + '@next/swc-linux-arm64-gnu@15.3.3': + optional: true + + '@next/swc-linux-arm64-musl@15.3.3': + optional: true + + '@next/swc-linux-x64-gnu@15.3.3': + optional: true + + '@next/swc-linux-x64-musl@15.3.3': + optional: true + + '@next/swc-win32-arm64-msvc@15.3.3': + optional: true + + '@next/swc-win32-x64-msvc@15.3.3': + optional: true + + '@orama/orama@3.1.7': {} + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.2': {} + + '@radix-ui/react-accordion@1.2.11(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collapsible': 1.1.11(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-collapsible@1.1.11(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-context@1.1.2(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-dialog@1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + aria-hidden: 1.2.6 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-direction@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-focus-guards@1.1.2(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-id@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-navigation-menu@1.2.13(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-popover@1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + aria-hidden: 1.2.6 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-popper@1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/react-dom': 2.1.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/rect': 1.1.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-presence@1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-scroll-area@1.2.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-slot@1.2.3(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-tabs@1.1.12(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.8)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.8)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.8 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + '@types/react-dom': 19.1.6(@types/react@19.1.8) + + '@radix-ui/rect@1.1.1': {} + + '@shikijs/core@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.3 + + '@shikijs/engine-oniguruma@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + + '@shikijs/rehype@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + shiki: 3.7.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + '@shikijs/themes@3.7.0': + dependencies: + '@shikijs/types': 3.7.0 + + '@shikijs/transformers@3.7.0': + dependencies: + '@shikijs/core': 3.7.0 + '@shikijs/types': 3.7.0 + + '@shikijs/types@3.7.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@standard-schema/spec@1.0.0': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.1.10': + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.10 + + '@tailwindcss/oxide-android-arm64@4.1.10': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.10': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.10': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.10': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.10': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.10': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.10': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.10': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.10': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.10': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.10': + optional: true + + '@tailwindcss/oxide@4.1.10': + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-x64': 4.1.10 + '@tailwindcss/oxide-freebsd-x64': 4.1.10 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.10 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.10 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-x64-musl': 4.1.10 + '@tailwindcss/oxide-wasm32-wasi': 4.1.10 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.10 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.10 + + '@tailwindcss/postcss@4.1.10': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.10 + '@tailwindcss/oxide': 4.1.10 + postcss: 8.5.6 + tailwindcss: 4.1.10 + + '@types/d3-array@3.2.1': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.6': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.7': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.6 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/geojson@7946.0.16': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + + '@types/node@22.15.28': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.1.6(@types/react@19.1.8)': + dependencies: + '@types/react': 19.1.8 + + '@types/react@19.1.8': + dependencies: + csstype: 3.1.3 + + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.0': {} + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + astring@1.9.0: {} + + bail@2.0.2: {} + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + caniuse-lite@1.0.30001724: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chevrotain-allstar@0.3.1(chevrotain@11.0.3): + dependencies: + chevrotain: 11.0.3 + lodash-es: 4.17.21 + + chevrotain@11.0.3: + dependencies: + '@chevrotain/cst-dts-gen': 11.0.3 + '@chevrotain/gast': 11.0.3 + '@chevrotain/regexp-to-ast': 11.0.3 + '@chevrotain/types': 11.0.3 + '@chevrotain/utils': 11.0.3 + lodash-es: 4.17.21 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@3.0.0: {} + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + client-only@0.0.1: {} + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + optional: true + + color-name@1.1.4: + optional: true + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + comma-separated-tokens@2.0.3: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + compute-scroll-into-view@3.1.1: {} + + confbox@0.1.8: {} + + confbox@0.2.2: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + cssesc@3.0.0: {} + + csstype@3.1.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.32.1): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.32.1 + + cytoscape-fcose@2.2.0(cytoscape@3.32.1): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.32.1 + + cytoscape@3.32.1: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.11: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + + dayjs@1.11.13: {} + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + dequal@2.0.3: {} + + detect-libc@2.0.4: {} + + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dompurify@3.2.6: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.2 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.2 + + esbuild@0.25.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + escape-string-regexp@5.0.0: {} + + esprima@4.0.1: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.4 + + estree-util-value-to-estree@3.4.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + exsolve@1.0.7: {} + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fdir@6.4.6(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fumadocs-core@15.5.1(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@formatjs/intl-localematcher': 0.6.1 + '@orama/orama': 3.1.7 + '@shikijs/rehype': 3.7.0 + '@shikijs/transformers': 3.7.0 + github-slugger: 2.0.0 + hast-util-to-estree: 3.1.3 + hast-util-to-jsx-runtime: 2.3.6 + image-size: 2.0.2 + negotiator: 1.0.0 + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) + remark: 15.0.1 + remark-gfm: 4.0.1 + remark-rehype: 11.1.2 + scroll-into-view-if-needed: 3.1.0 + shiki: 3.7.0 + unist-util-visit: 5.0.0 + optionalDependencies: + next: 15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + transitivePeerDependencies: + - '@types/react' + - supports-color + + fumadocs-mdx@11.6.7(acorn@8.15.0)(fumadocs-core@15.5.1(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): + dependencies: + '@mdx-js/mdx': 3.1.0(acorn@8.15.0) + '@standard-schema/spec': 1.0.0 + chokidar: 4.0.3 + esbuild: 0.25.5 + estree-util-value-to-estree: 3.4.0 + fumadocs-core: 15.5.1(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + gray-matter: 4.0.3 + js-yaml: 4.1.0 + lru-cache: 11.1.0 + next: 15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + picocolors: 1.1.1 + tinyexec: 1.0.1 + tinyglobby: 0.2.14 + unist-util-visit: 5.0.0 + zod: 3.25.76 + transitivePeerDependencies: + - acorn + - supports-color + + fumadocs-ui@15.5.1(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.1.10): + dependencies: + '@radix-ui/react-accordion': 1.2.11(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collapsible': 1.1.11(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-navigation-menu': 1.2.13(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-popover': 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-scroll-area': 1.2.9(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-tabs': 1.1.12(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + class-variance-authority: 0.7.1 + fumadocs-core: 15.5.1(@types/react@19.1.8)(next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + lodash.merge: 4.6.2 + next: 15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-themes: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + postcss-selector-parser: 7.1.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-medium-image-zoom: 5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.8)(react@19.1.0) + tailwind-merge: 3.3.1 + optionalDependencies: + tailwindcss: 4.1.10 + transitivePeerDependencies: + - '@oramacloud/client' + - '@types/react' + - '@types/react-dom' + - algoliasearch + - supports-color + + get-nonce@1.0.1: {} + + github-slugger@2.0.0: {} + + globals@15.15.0: {} + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + hachure-fill@0.5.2: {} + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.17 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.17 + unist-util-position: 5.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + html-void-elements@3.0.0: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + image-size@2.0.2: {} + + inline-style-parser@0.2.4: {} + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.3.2: + optional: true + + is-decimal@2.0.1: {} + + is-extendable@0.1.1: {} + + is-hexadecimal@2.0.1: {} + + is-plain-obj@4.1.0: {} + + jiti@2.4.2: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + katex@0.16.22: + dependencies: + commander: 8.3.0 + + khroma@2.1.0: {} + + kind-of@6.0.3: {} + + kolorist@1.8.0: {} + + langium@3.3.1: + dependencies: + chevrotain: 11.0.3 + chevrotain-allstar: 0.3.1(chevrotain@11.0.3) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.0.4 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + + local-pkg@1.1.1: + dependencies: + mlly: 1.7.4 + pkg-types: 2.2.0 + quansync: 0.2.10 + + lodash-es@4.17.21: {} + + lodash.merge@4.6.2: {} + + longest-streak@3.1.0: {} + + lru-cache@11.1.0: {} + + lucide-react@0.525.0(react@19.1.0): + dependencies: + react: 19.1.0 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + marked@15.0.12: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mermaid@11.8.1: + dependencies: + '@braintree/sanitize-url': 7.1.1 + '@iconify/utils': 2.3.0 + '@mermaid-js/parser': 0.6.1 + '@types/d3': 7.4.3 + cytoscape: 3.32.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.32.1) + cytoscape-fcose: 2.2.0(cytoscape@3.32.1) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.11 + dayjs: 1.11.13 + dompurify: 3.2.6 + katex: 0.16.22 + khroma: 2.1.0 + lodash-es: 4.17.21 + marked: 15.0.12 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + transitivePeerDependencies: + - supports-color + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.2 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.2 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.1 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + minipass@7.1.2: {} + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mkdirp@3.0.1: {} + + mlly@1.7.4: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + negotiator@1.0.0: {} + + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + next@15.3.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@next/env': 15.3.3 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001724 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.3 + '@next/swc-darwin-x64': 15.3.3 + '@next/swc-linux-arm64-gnu': 15.3.3 + '@next/swc-linux-arm64-musl': 15.3.3 + '@next/swc-linux-x64-gnu': 15.3.3 + '@next/swc-linux-x64-musl': 15.3.3 + '@next/swc-win32-arm64-msvc': 15.3.3 + '@next/swc-win32-x64-msvc': 15.3.3 + sharp: 0.34.2 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.3: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.0.1 + regex-recursion: 6.0.2 + + package-manager-detector@1.3.0: {} + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + path-data-parser@0.1.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.2: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 + + pkg-types@2.2.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.7 + pathe: 2.0.3 + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + postcss-selector-parser@7.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.6.2: {} + + property-information@7.1.0: {} + + quansync@0.2.10: {} + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-medium-image-zoom@5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-remove-scroll-bar@2.3.8(@types/react@19.1.8)(react@19.1.0): + dependencies: + react: 19.1.0 + react-style-singleton: 2.2.3(@types/react@19.1.8)(react@19.1.0) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.8 + + react-remove-scroll@2.7.1(@types/react@19.1.8)(react@19.1.0): + dependencies: + react: 19.1.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.8)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.8)(react@19.1.0) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.8)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.8)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.8 + + react-style-singleton@2.2.3(@types/react@19.1.8)(react@19.1.0): + dependencies: + get-nonce: 1.0.1 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.8 + + react@19.1.0: {} + + readdirp@4.1.2: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.0(acorn@8.15.0): + dependencies: + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - acorn + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.0.1: + dependencies: + regex-utilities: 2.3.0 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.0: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remark@15.0.1: + dependencies: + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + robust-predicates@3.0.2: {} + + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + rw@1.3.3: {} + + safer-buffer@2.1.2: {} + + scheduler@0.26.0: {} + + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver@7.7.2: + optional: true + + sharp@0.34.2: + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 + optional: true + + shiki@3.7.0: + dependencies: + '@shikijs/core': 3.7.0 + '@shikijs/engine-javascript': 3.7.0 + '@shikijs/engine-oniguruma': 3.7.0 + '@shikijs/langs': 3.7.0 + '@shikijs/themes': 3.7.0 + '@shikijs/types': 3.7.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + + source-map-js@1.2.1: {} + + source-map@0.7.4: {} + + space-separated-tokens@2.0.2: {} + + sprintf-js@1.0.3: {} + + streamsearch@1.1.0: {} + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-bom-string@1.0.0: {} + + style-to-js@1.1.17: + dependencies: + style-to-object: 1.0.9 + + style-to-object@1.0.9: + dependencies: + inline-style-parser: 0.2.4 + + styled-jsx@5.1.6(react@19.1.0): + dependencies: + client-only: 0.0.1 + react: 19.1.0 + + stylis@4.3.6: {} + + tailwind-merge@3.3.1: {} + + tailwindcss@4.1.10: {} + + tapable@2.2.2: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + tinyexec@1.0.1: {} + + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-dedent@2.2.0: {} + + tslib@2.8.1: {} + + typescript@5.8.3: {} + + ufo@1.6.1: {} + + undici-types@6.21.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + use-callback-ref@1.3.3(@types/react@19.1.8)(react@19.1.0): + dependencies: + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.8 + + use-sidecar@1.1.3(@types/react@19.1.8)(react@19.1.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.8 + + util-deprecate@1.0.2: {} + + uuid@11.1.0: {} + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.0.8: {} + + yallist@5.0.0: {} + + zod@3.25.76: {} + + zwitch@2.0.4: {} diff --git a/docs/postcss.config.mjs b/docs/postcss.config.mjs new file mode 100644 index 00000000..a34a3d56 --- /dev/null +++ b/docs/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/docs/public/img/agent.png b/docs/public/img/agent.png new file mode 100644 index 00000000..bcca2358 Binary files /dev/null and b/docs/public/img/agent.png differ diff --git a/docs/public/img/agent_gradio_ui.png b/docs/public/img/agent_gradio_ui.png new file mode 100644 index 00000000..df871da5 Binary files /dev/null and b/docs/public/img/agent_gradio_ui.png differ diff --git a/docs/public/img/cli.png b/docs/public/img/cli.png new file mode 100644 index 00000000..2d0b6465 Binary files /dev/null and b/docs/public/img/cli.png differ diff --git a/docs/public/img/computer.png b/docs/public/img/computer.png new file mode 100644 index 00000000..c0b32946 Binary files /dev/null and b/docs/public/img/computer.png differ diff --git a/docs/source.config.ts b/docs/source.config.ts new file mode 100644 index 00000000..c3b9e719 --- /dev/null +++ b/docs/source.config.ts @@ -0,0 +1,31 @@ +import { + defineConfig, + defineDocs, + frontmatterSchema, + metaSchema, +} from 'fumadocs-mdx/config'; +import { z } from 'zod'; + +// You can customise Zod schemas for frontmatter and `meta.json` here +// see https://fumadocs.vercel.app/docs/mdx/collections#define-docs +export const docs = defineDocs({ + docs: { + schema: frontmatterSchema.extend({ + pypi: z.string().optional(), + npm: z.string().optional(), + github: z.array(z.string()).optional(), + macos: z.boolean().default(false), + windows: z.boolean().default(false), + linux: z.boolean().default(false), + }), + }, + meta: { + schema: metaSchema, + }, +}); + +export default defineConfig({ + mdxOptions: { + // MDX options + }, +}); diff --git a/docs/src/app/(home)/[[...slug]]/page.tsx b/docs/src/app/(home)/[[...slug]]/page.tsx new file mode 100644 index 00000000..a9a36b4f --- /dev/null +++ b/docs/src/app/(home)/[[...slug]]/page.tsx @@ -0,0 +1,305 @@ +import { getApiVersions, source } from '@/lib/source'; +import { getMDXComponents } from '@/mdx-components'; +import { buttonVariants } from 'fumadocs-ui/components/ui/button'; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from 'fumadocs-ui/components/ui/popover'; +import { createRelativeLink } from 'fumadocs-ui/mdx'; +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, +} from 'fumadocs-ui/page'; +import { cn } from 'fumadocs-ui/utils/cn'; +import { ChevronDown, CodeXml, ExternalLink } from 'lucide-react'; +import type { Metadata } from 'next'; +import Link from 'next/link'; +import { notFound, redirect } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const slug = params.slug || []; + const page = source.getPage(slug); + if (!page) notFound(); //redirect('/docs'); + + // Detect if this is an API reference page: /api/[section] or /api/[section]/[version] + let apiSection: string | null = null; + let apiVersionSlug: string[] = []; + if (slug[0] === 'api' && slug.length >= 2) { + apiSection = slug[1]; + if (slug.length > 2) { + apiVersionSlug = slug.slice(2); + } + } + + let versionItems: { label: string; slug: string[] }[] = []; + if (apiSection) { + versionItems = await getApiVersions(apiSection); + } + + const macos = page.data.macos; + const windows = page.data.windows; + const linux = page.data.linux; + const pypi = page.data.pypi; + const npm = page.data.npm; + const github = page.data.github; + + const MDXContent = page.data.body; + + // Platform icons component + const PlatformIcons = () => { + const hasAnyPlatform = macos || windows || linux; + if (!hasAnyPlatform && !pypi) return null; + + return ( +
+ {hasAnyPlatform && ( +
+ {windows && ( + + Windows + + + )} + {macos && ( + + macOS + + + )} + {linux && ( + + Linux + + + )} +
+ )} + +
+ {pypi && ( + + PyPI + + )} + {npm && ( + + NPM + + )} +
+
+ ); + }; + + const tocHeader = () => { + return ( +
+ +
+ {github && + github.length > 0 && + (github.length === 1 ? ( + + + + + Source + + + ) : ( + + + + + + Source + + + + + + + ))} + {slug.includes('libraries') && ( + + + Reference + + )} +
+
+
+ ); + }; + + return ( + +
+
+
+ {page.data.title} + +
+ {apiSection && versionItems.length > 1 && ( + + + {(() => { + // Find the current version label + let currentLabel = 'Current'; + if (apiVersionSlug.length > 0) { + const found = versionItems.find( + (item) => + item.label !== 'Current' && + apiVersionSlug[0] === item.label + ); + if (found) currentLabel = found.label; + } + return ( + <> + API Version: {currentLabel} + + + ); + })()} + + + {versionItems.map((item) => { + // Build the href for each version + const href = + item.label === 'Current' + ? `/api/${apiSection}` + : `/api/${apiSection}/${item.label}`; + // Highlight current version + const isCurrent = + (item.label === 'Current' && + apiVersionSlug.length === 0) || + (item.label !== 'Current' && + apiVersionSlug[0] === item.label); + return ( + + API version: {item.label} + + ); + })} + + + )} +
+
+ + {page.data.description} + +
+
+ + + +
+ ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata(props: { + params: Promise<{ slug?: string[] }>; +}): Promise { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + let title = `${page.data.title} | Cua Docs`; + if (page.url.includes('api')) title = `${page.data.title} | Cua API Docs`; + if (page.url.includes('guide')) + title = ` Guide: ${page.data.title} | Cua Docs`; + + return { + title, + description: page.data.description, + openGraph: { + title, + description: page.data.description, + type: 'article', + siteName: 'Cua Docs', + url: 'https://trycua.com/docs', + }, + }; +} diff --git a/docs/src/app/(home)/layout.tsx b/docs/src/app/(home)/layout.tsx new file mode 100644 index 00000000..f73f4f1d --- /dev/null +++ b/docs/src/app/(home)/layout.tsx @@ -0,0 +1,12 @@ +import { baseOptions } from '@/app/layout.config'; +import { source } from '@/lib/source'; +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import type { ReactNode } from 'react'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/docs/src/app/api/search/route.ts b/docs/src/app/api/search/route.ts new file mode 100644 index 00000000..df889626 --- /dev/null +++ b/docs/src/app/api/search/route.ts @@ -0,0 +1,4 @@ +import { source } from '@/lib/source'; +import { createFromSource } from 'fumadocs-core/search/server'; + +export const { GET } = createFromSource(source); diff --git a/docs/src/app/favicon.ico b/docs/src/app/favicon.ico new file mode 100644 index 00000000..dd75e7d8 Binary files /dev/null and b/docs/src/app/favicon.ico differ diff --git a/docs/src/app/global.css b/docs/src/app/global.css new file mode 100644 index 00000000..50b3bc29 --- /dev/null +++ b/docs/src/app/global.css @@ -0,0 +1,3 @@ +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; diff --git a/docs/src/app/layout.config.tsx b/docs/src/app/layout.config.tsx new file mode 100644 index 00000000..f29509bd --- /dev/null +++ b/docs/src/app/layout.config.tsx @@ -0,0 +1,74 @@ +import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; + +import Image from 'next/image'; +import LogoBlack from '@/assets/logo-black.svg'; +import LogoWhite from '@/assets/logo-white.svg'; +import DiscordWhite from '@/assets/discord-white.svg'; +import DiscordBlack from '@/assets/discord-black.svg'; +import { HomeIcon } from 'lucide-react'; + +/** + * Shared layout configurations + * + * you can customise layouts individually from: + * Home Layout: app/(home)/layout.tsx + * Docs Layout: app/docs/layout.tsx + */ +export const baseOptions: BaseLayoutProps = { + nav: { + title: ( + <> + Logo + Logo + Cua Documentation + + ), + }, + githubUrl: 'https://github.com/trycua/cua', + links: [ + { + url: 'https://trycua.com', + text: 'cua home', + type: 'icon', + icon: , + external: false, + }, + { + url: 'https://discord.com/invite/mVnXXpdE85', + text: 'cua discord', + type: 'icon', + icon: ( + <> + Discord + Discord + + ), + }, + ], +}; diff --git a/docs/src/app/layout.tsx b/docs/src/app/layout.tsx new file mode 100644 index 00000000..74da946a --- /dev/null +++ b/docs/src/app/layout.tsx @@ -0,0 +1,21 @@ +import './global.css'; +import { RootProvider } from 'fumadocs-ui/provider'; +import { Inter } from 'next/font/google'; +import type { ReactNode } from 'react'; + +const inter = Inter({ + subsets: ['latin'], +}); + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + + + + + {children} + + + ); +} diff --git a/docs/src/app/llms.mdx/[[...slug]]/route.ts b/docs/src/app/llms.mdx/[[...slug]]/route.ts new file mode 100644 index 00000000..15b8e678 --- /dev/null +++ b/docs/src/app/llms.mdx/[[...slug]]/route.ts @@ -0,0 +1,21 @@ +import { type NextRequest, NextResponse } from 'next/server'; +import { getLLMText } from '@/lib/llms'; +import { source } from '@/lib/source'; +import { notFound } from 'next/navigation'; + +export const revalidate = false; + +export async function GET( + _req: NextRequest, + { params }: { params: Promise<{ slug?: string[] }> } +) { + const { slug } = await params; + const page = source.getPage(slug); + if (!page) notFound(); + + return new NextResponse(await getLLMText(page)); +} + +export function generateStaticParams() { + return source.generateParams(); +} diff --git a/docs/src/app/llms.txt/route.ts b/docs/src/app/llms.txt/route.ts new file mode 100644 index 00000000..5c913bf1 --- /dev/null +++ b/docs/src/app/llms.txt/route.ts @@ -0,0 +1,12 @@ +import { source } from '@/lib/source'; +import { getLLMText } from '@/lib/llms'; + +// cached forever +export const revalidate = false; + +export async function GET() { + const scan = source.getPages().map(getLLMText); + const scanned = await Promise.all(scan); + + return new Response(scanned.join('\n\n')); +} diff --git a/docs/src/assets/discord-black.svg b/docs/src/assets/discord-black.svg new file mode 100644 index 00000000..c3b16e5e --- /dev/null +++ b/docs/src/assets/discord-black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/src/assets/discord-white.svg b/docs/src/assets/discord-white.svg new file mode 100644 index 00000000..bd25430e --- /dev/null +++ b/docs/src/assets/discord-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/src/assets/logo-black.svg b/docs/src/assets/logo-black.svg new file mode 100644 index 00000000..20f3aab0 --- /dev/null +++ b/docs/src/assets/logo-black.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/assets/logo-white.svg b/docs/src/assets/logo-white.svg new file mode 100644 index 00000000..ec40ab17 --- /dev/null +++ b/docs/src/assets/logo-white.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/components/iou.tsx b/docs/src/components/iou.tsx new file mode 100644 index 00000000..275f2c4d --- /dev/null +++ b/docs/src/components/iou.tsx @@ -0,0 +1,106 @@ +'use client'; +import React, { useRef, useEffect, useState, useCallback } from 'react'; + +interface Rectangle { + left: number; + top: number; + width: number; + height: number; + fill: string; + name: string; +} + +interface IOUProps { + title: string; + description: string; + rect1: Rectangle; + rect2: Rectangle; +} + +export default function IOU({ title, description, rect1, rect2 }: IOUProps) { + const canvasRef = useRef(null); + const [actualIOU, setActualIOU] = useState(0); + + const getBbox = (rect: Rectangle) => ({ + left: rect.left, + right: rect.left + rect.width, + top: rect.top, + bottom: rect.top + rect.height, + }); + + const calcIntersection = (bbox1: any, bbox2: any): number => { + const x1 = Math.max(bbox1.left, bbox2.left); + const x2 = Math.min(bbox1.right, bbox2.right); + const y1 = Math.max(bbox1.top, bbox2.top); + const y2 = Math.min(bbox1.bottom, bbox2.bottom); + + // Check if there's actually an overlap + if (x2 <= x1 || y2 <= y1) { + return 0; + } + + const intersection = (x2 - x1) * (y2 - y1); + return intersection; + }; + + const calcArea = (rect: Rectangle): number => { + return rect.width * rect.height; + }; + + const drawCanvas = useCallback(() => { + const canvas = canvasRef.current; + if (!canvas) return; + + const ctx = canvas.getContext('2d'); + if (!ctx) return; + + // Clear canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Calculate IOU + const bbox1 = getBbox(rect1); + const bbox2 = getBbox(rect2); + const intersection = calcIntersection(bbox1, bbox2); + const union = calcArea(rect1) + calcArea(rect2) - intersection; + const iou = intersection / union; + setActualIOU(iou); + + // Draw rectangles + [rect1, rect2].forEach((rect) => { + ctx.fillStyle = rect.fill; + ctx.fillRect(rect.left, rect.top, rect.width, rect.height); + + ctx.strokeStyle = '#000'; + ctx.lineWidth = 2; + ctx.strokeRect(rect.left, rect.top, rect.width, rect.height); + + ctx.fillStyle = '#000'; + ctx.font = '12px'; + ctx.fillText(rect.name, rect.left + 5, rect.top + 15); + }); + }, [rect1, rect2]); + + useEffect(() => { + drawCanvas(); + }, [drawCanvas]); + + return ( +
+

{title}

+
+
+ +
+
IOU = {actualIOU.toFixed(3)}
+ {description} +
+
+
+
+ ); +} diff --git a/docs/src/components/mermaid.tsx b/docs/src/components/mermaid.tsx new file mode 100644 index 00000000..e22c31bd --- /dev/null +++ b/docs/src/components/mermaid.tsx @@ -0,0 +1,47 @@ +'use client'; + +import { useEffect, useId, useRef, useState } from 'react'; +import { useTheme } from 'next-themes'; + +export function Mermaid({ chart }: { chart: string }) { + const id = useId(); + const [svg, setSvg] = useState(''); + const containerRef = useRef(null); + const currentChartRef = useRef(null); + const { resolvedTheme } = useTheme(); + + useEffect(() => { + if (currentChartRef.current === chart || !containerRef.current) return; + const container = containerRef.current; + currentChartRef.current = chart; + + async function renderChart() { + const { default: mermaid } = await import('mermaid'); + + try { + // configure mermaid + mermaid.initialize({ + startOnLoad: false, + securityLevel: 'loose', + fontFamily: 'inherit', + themeCSS: 'margin: 1.5rem auto 0;', + theme: resolvedTheme === 'dark' ? 'dark' : 'default', + }); + + const { svg, bindFunctions } = await mermaid.render( + id, + chart.replaceAll('\\n', '\n'), + ); + + bindFunctions?.(container); + setSvg(svg); + } catch (error) { + console.error('Error while rendering mermaid', error); + } + } + + void renderChart(); + }, [chart, id, resolvedTheme]); + + return
; +} \ No newline at end of file diff --git a/docs/src/lib/llms.ts b/docs/src/lib/llms.ts new file mode 100644 index 00000000..e485bed2 --- /dev/null +++ b/docs/src/lib/llms.ts @@ -0,0 +1,26 @@ +import { remark } from 'remark'; +import remarkGfm from 'remark-gfm'; +import remarkMdx from 'remark-mdx'; +import { remarkInclude } from 'fumadocs-mdx/config'; +import { source } from '@/lib/source'; +import type { InferPageType } from 'fumadocs-core/source'; + +const processor = remark() + .use(remarkMdx) + // needed for Fumadocs MDX + .use(remarkInclude) + .use(remarkGfm); + +export async function getLLMText(page: InferPageType) { + const processed = await processor.process({ + path: page.data._file.absolutePath, + value: page.data.content, + }); + + return `# ${page.data.title} +URL: ${page.url} + +${page.data.description} + +${processed.value}`; +} diff --git a/docs/src/lib/source.ts b/docs/src/lib/source.ts new file mode 100644 index 00000000..a202cf80 --- /dev/null +++ b/docs/src/lib/source.ts @@ -0,0 +1,52 @@ +import { docs } from '@/.source'; +import { loader } from 'fumadocs-core/source'; +import { icons } from 'lucide-react'; +import { createElement } from 'react'; + +import fs from 'node:fs/promises'; +import path from 'node:path'; + +/** + * Returns available API doc versions for a given section (e.g., 'agent'). + * Each version is an object: { label, slug } + * - 'Current' (index.mdx) → slug: [] + * - '[version].mdx' → slug: [version] + */ +export async function getApiVersions( + section: string +): Promise<{ label: string; slug: string[] }[]> { + const dir = path.join(process.cwd(), 'content/docs/api', section); + let files: string[] = []; + try { + files = (await fs.readdir(dir)).filter((f) => f.endsWith('.mdx')); + } catch (_e) { + return []; + } + const versions = files.map((file) => { + if (file === 'index.mdx') { + return { label: 'Current', slug: [] }; + } + const version = file.replace(/\.mdx$/, ''); + return { label: version, slug: [version] }; + }); + // Always put 'Current' first, then others sorted descending (semver-ish) + return [ + ...versions.filter((v) => v.label === 'Current'), + ...versions + .filter((v) => v.label !== 'Current') + .sort((a, b) => + b.label.localeCompare(a.label, undefined, { numeric: true }) + ), + ]; +} + +// See https://fumadocs.vercel.app/docs/headless/source-api for more info +export const source = loader({ + // it assigns a URL to your pages + baseUrl: '/', + source: docs.toFumadocsSource(), + icon(icon) { + if (!icon) return; + if (icon in icons) return createElement(icons[icon as keyof typeof icons]); + }, +}); diff --git a/docs/src/mdx-components.tsx b/docs/src/mdx-components.tsx new file mode 100644 index 00000000..3b27cf8c --- /dev/null +++ b/docs/src/mdx-components.tsx @@ -0,0 +1,16 @@ +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import * as TabsComponents from 'fumadocs-ui/components/tabs'; +import type { MDXComponents } from 'mdx/types'; +import { Mermaid } from './components/mermaid'; +import IOU from './components/iou'; + +// use this function to get MDX components, you will need it for rendering MDX +export function getMDXComponents(components?: MDXComponents): MDXComponents { + return { + ...defaultMdxComponents, + Mermaid, + IOU, + ...TabsComponents, + ...components, + }; +} diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 00000000..504b2911 --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,45 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ESNext", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/.source": [ + "./.source/index.ts" + ], + "@/*": [ + "./src/*" + ] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/examples/agent_examples.py b/examples/agent_examples.py index d6a565bf..4d211f7f 100644 --- a/examples/agent_examples.py +++ b/examples/agent_examples.py @@ -29,7 +29,7 @@ async def run_agent_example(): verbosity=logging.DEBUG, ) - # Create a remote Linux computer with C/ua + # Create a remote Linux computer with Cua # computer = Computer( # os_type="linux", # api_key=os.getenv("CUA_API_KEY"), diff --git a/examples/agent_ui_examples.py b/examples/agent_ui_examples.py index d5a37119..97f54856 100644 --- a/examples/agent_ui_examples.py +++ b/examples/agent_ui_examples.py @@ -13,7 +13,7 @@ from utils import load_dotenv_files load_dotenv_files() # Import the create_gradio_ui function -from agent.ui.gradio.app import create_gradio_ui +from agent.ui.gradio.ui_components import create_gradio_ui if __name__ == "__main__": print("Launching Computer-Use Agent Gradio UI with advanced features...") diff --git a/examples/computer-example-ts/README.md b/examples/computer-example-ts/README.md index 1e61eab0..935588aa 100644 --- a/examples/computer-example-ts/README.md +++ b/examples/computer-example-ts/README.md @@ -1,10 +1,10 @@ # cua-cloud-openai Example -This example demonstrates how to control a c/ua Cloud container using the OpenAI `computer-use-preview` model and the `@trycua/computer` TypeScript library. +This example demonstrates how to control a cua Cloud container using the OpenAI `computer-use-preview` model and the `@trycua/computer` TypeScript library. ## Overview -- Connects to a c/ua Cloud container via the `@trycua/computer` library +- Connects to a cua Cloud container via the `@trycua/computer` library - Sends screenshots and instructions to OpenAI's computer-use model - Executes AI-generated actions (clicks, typing, etc.) inside the container - Designed for Linux containers, but can be adapted for other OS types @@ -20,7 +20,7 @@ This example demonstrates how to control a c/ua Cloud container using the OpenAI 2. **Set up environment variables:** Create a `.env` file with the following variables: - `OPENAI_KEY` — your OpenAI API key - - `CUA_KEY` — your c/ua Cloud API key + - `CUA_KEY` — your cua Cloud API key - `CUA_CONTAINER_NAME` — the name of your provisioned container 3. **Run the example:** @@ -38,7 +38,7 @@ This example demonstrates how to control a c/ua Cloud container using the OpenAI For a step-by-step tutorial and more detailed explanation, see the accompanying blog post: -➡️ [Controlling a c/ua Cloud Container with JavaScript](https://placeholder-url-to-blog-post.com) +➡️ [Controlling a cua Cloud Container with JavaScript](https://placeholder-url-to-blog-post.com) _(This link will be updated once the article is published.)_ diff --git a/examples/computer_examples.py b/examples/computer_examples.py index 227beb8c..bb9e7ad9 100644 --- a/examples/computer_examples.py +++ b/examples/computer_examples.py @@ -43,7 +43,7 @@ async def main(): ephemeral=False, ) - # Create a remote Linux computer with C/ua + # Create a remote Linux computer with Cua # computer = Computer( # os_type="linux", # api_key=os.getenv("CUA_API_KEY"), diff --git a/examples/sandboxed_functions_examples.py b/examples/sandboxed_functions_examples.py index caa733b9..93d93021 100644 --- a/examples/sandboxed_functions_examples.py +++ b/examples/sandboxed_functions_examples.py @@ -22,7 +22,7 @@ from computer.computer import Computer from computer.helpers import sandboxed async def main(): - # Initialize the computer in a C/ua Container + # Initialize the computer in a Cua Container computer = Computer() await computer.run() @@ -34,7 +34,7 @@ async def main(): await asyncio.sleep(2) # Define a sandboxed function - # This function will run inside the C/ua Container + # This function will run inside the Cua Container @sandboxed("demo_venv") def greet_and_print(name): # get .html of the current Safari tab @@ -47,7 +47,7 @@ async def main(): return {"greeted": name, "safari_html_length": len(html), "safari_html_snippet": html[:200]} # Call with args and kwargs - result = await greet_and_print("C/ua") + result = await greet_and_print("Cua") print("Result from sandboxed function:", result) if __name__ == "__main__": diff --git a/libs/python/agent/agent/adapters/huggingfacelocal_adapter.py b/libs/python/agent/agent/adapters/huggingfacelocal_adapter.py index 5692401d..e8281114 100644 --- a/libs/python/agent/agent/adapters/huggingfacelocal_adapter.py +++ b/libs/python/agent/agent/adapters/huggingfacelocal_adapter.py @@ -8,7 +8,7 @@ from litellm import completion, acompletion # Try to import HuggingFace dependencies try: import torch - from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor + from transformers import AutoModelForImageTextToText, AutoProcessor HF_AVAILABLE = True except ImportError: HF_AVAILABLE = False @@ -40,7 +40,7 @@ class HuggingFaceLocalAdapter(CustomLLM): """ if model_name not in self.models: # Load model - model = Qwen2_5_VLForConditionalGeneration.from_pretrained( + model = AutoModelForImageTextToText.from_pretrained( model_name, torch_dtype=torch.float16, device_map=self.device, @@ -145,8 +145,7 @@ class HuggingFaceLocalAdapter(CustomLLM): ) # Move inputs to the same device as model - if torch.cuda.is_available() and self.device != "cpu": - inputs = inputs.to("cuda") + inputs = inputs.to(model.device) # Generate response with torch.no_grad(): diff --git a/libs/python/agent/agent/agent.py b/libs/python/agent/agent/agent.py index 06f617c2..79a4b9a6 100644 --- a/libs/python/agent/agent/agent.py +++ b/libs/python/agent/agent/agent.py @@ -422,6 +422,9 @@ class ComputerAgent: # Perform computer actions action = item.get("action") action_type = action.get("type") + if action_type is None: + print(f"Action type cannot be `None`: action={action}, action_type={action_type}") + return [] # Extract action arguments (all fields except 'type') action_args = {k: v for k, v in action.items() if k != "type"} diff --git a/libs/python/agent/agent/callbacks/pii_anonymization.py b/libs/python/agent/agent/callbacks/pii_anonymization.py index 592b7273..68f4b2fc 100644 --- a/libs/python/agent/agent/callbacks/pii_anonymization.py +++ b/libs/python/agent/agent/callbacks/pii_anonymization.py @@ -93,4 +93,4 @@ class PIIAnonymizationCallback(AsyncCallbackHandler): async def _deanonymize_item(self, item: Dict[str, Any]) -> Dict[str, Any]: # TODO: Implement _deanonymize_item - return item \ No newline at end of file + return item diff --git a/libs/python/agent/agent/ui/gradio/app.py b/libs/python/agent/agent/ui/gradio/app.py index 13c0786f..be04d931 100644 --- a/libs/python/agent/agent/ui/gradio/app.py +++ b/libs/python/agent/agent/ui/gradio/app.py @@ -178,13 +178,20 @@ def create_computer_instance( """Create or get the global Computer instance.""" global global_computer if global_computer is None: - global_computer = Computer( - verbosity=verbosity, - os_type=os_type, - provider_type=provider_type, - name=name if name else "", - api_key=api_key - ) + if provider_type == "localhost": + global_computer = Computer( + verbosity=verbosity, + os_type=os_type, + use_host_computer_server=True + ) + else: + global_computer = Computer( + verbosity=verbosity, + os_type=os_type, + provider_type=provider_type, + name=name if name else "", + api_key=api_key + ) return global_computer diff --git a/libs/python/agent/agent/ui/gradio/ui_components.py b/libs/python/agent/agent/ui/gradio/ui_components.py index dfcceb4e..c601fb6c 100644 --- a/libs/python/agent/agent/ui/gradio/ui_components.py +++ b/libs/python/agent/agent/ui/gradio/ui_components.py @@ -211,7 +211,7 @@ if __name__ == "__main__": is_windows = platform.system().lower() == "windows" is_mac = platform.system().lower() == "darwin" - providers = ["cloud"] + providers = ["cloud", "localhost"] if is_mac: providers += ["lume"] if is_windows: @@ -403,6 +403,23 @@ if __name__ == "__main__": type="password", ) + # Provider visibility update function + def update_provider_visibility(provider): + """Update visibility of container name and API key based on selected provider.""" + is_localhost = provider == "localhost" + return [ + gr.update(visible=not is_localhost), # container_name + gr.update(visible=not is_localhost and not has_cua_key) # cua_cloud_api_key + ] + + # Connect provider change event + computer_provider.change( + fn=update_provider_visibility, + inputs=[computer_provider], + outputs=[container_name, cua_cloud_api_key], + queue=False + ) + # Connect UI update events for dropdown in [agent_loop, omni_model_choice, uitars_model_choice, openai_model_choice, anthropic_model_choice]: dropdown.change( diff --git a/libs/python/agent/pyproject.toml b/libs/python/agent/pyproject.toml index 232aaa48..75f8159a 100644 --- a/libs/python/agent/pyproject.toml +++ b/libs/python/agent/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ "pydantic>=2.6.4", "rich>=13.7.1", "python-dotenv>=1.0.1", - "cua-computer>=0.3.0,<0.5.0", + "cua-computer>=0.4.0,<0.5.0", "cua-core>=0.1.8,<0.2.0", "certifi>=2024.2.2", "litellm>=1.74.12" diff --git a/libs/python/computer/computer/ui/gradio/app.py b/libs/python/computer/computer/ui/gradio/app.py index 8c3708db..d8c5c513 100644 --- a/libs/python/computer/computer/ui/gradio/app.py +++ b/libs/python/computer/computer/ui/gradio/app.py @@ -302,7 +302,7 @@ def upload_to_huggingface(dataset_name, visibility, filter_tags=None): ) card = DatasetCard.from_template( card_data=card_data, - template_str="---\n{{ card_data }}\n---\n\n# Uploaded computer interface trajectories\n\nThese trajectories were generated and uploaded using [c/ua](https://github.com/trycua/cua)" + template_str="---\n{{ card_data }}\n---\n\n# Uploaded computer interface trajectories\n\nThese trajectories were generated and uploaded using [cua](https://github.com/trycua/cua)" ) card.push_to_hub( dataset_name, diff --git a/libs/python/computer/pyproject.toml b/libs/python/computer/pyproject.toml index 2e564fa9..4a9b41bb 100644 --- a/libs/python/computer/pyproject.toml +++ b/libs/python/computer/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "pdm.backend" [project] name = "cua-computer" -version = "0.3.0" +version = "0.4.0" description = "Computer-Use Interface (CUI) framework powering Cua" readme = "README.md" authors = [ diff --git a/libs/python/mcp-server/README.md b/libs/python/mcp-server/README.md index 3f3c8bbb..a94da8a7 100644 --- a/libs/python/mcp-server/README.md +++ b/libs/python/mcp-server/README.md @@ -16,6 +16,21 @@
**cua-mcp-server** is a MCP server for the Computer-Use Agent (CUA), allowing you to run CUA through Claude Desktop or other MCP clients. + +## LiteLLM Integration + +This MCP server features comprehensive liteLLM integration, allowing you to use any supported LLM provider with a simple model string configuration. + +- **Unified Configuration**: Use a single `CUA_MODEL_NAME` environment variable with a model string +- **Automatic Provider Detection**: The agent automatically detects the provider and capabilities from the model string +- **Extensive Provider Support**: Works with Anthropic, OpenAI, local models, and any liteLLM-compatible provider + +### Model String Examples: +- **Anthropic**: `"anthropic/claude-3-5-sonnet-20241022"` +- **OpenAI**: `"openai/computer-use-preview"` +- **UI-TARS**: `"huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B"` +- **Omni + Any LiteLLM**: `"omniparser+litellm/gpt-4o"`, `"omniparser+litellm/claude-3-haiku"`, `"omniparser+ollama_chat/gemma3"` + ### Get started with Agent ## Prerequisites @@ -65,10 +80,7 @@ You can then use the script in your MCP configuration like this: "command": "/bin/bash", "args": ["~/.cua/start_mcp_server.sh"], "env": { - "CUA_AGENT_LOOP": "OMNI", - "CUA_MODEL_PROVIDER": "ANTHROPIC", - "CUA_MODEL_NAME": "claude-3-7-sonnet-20250219", - "CUA_PROVIDER_API_KEY": "your-api-key" + "CUA_MODEL_NAME": "anthropic/claude-3-5-sonnet-20241022" } } } @@ -86,11 +98,7 @@ If you want to develop with the cua-mcp-server directly without installation, yo "command": "/bin/bash", "args": ["~/cua/libs/python/mcp-server/scripts/start_mcp_server.sh"], "env": { - "CUA_AGENT_LOOP": "UITARS", - "CUA_MODEL_PROVIDER": "OAICOMPAT", - "CUA_MODEL_NAME": "ByteDance-Seed/UI-TARS-1.5-7B", - "CUA_PROVIDER_BASE_URL": "https://****************.us-east-1.aws.endpoints.huggingface.cloud/v1", - "CUA_PROVIDER_API_KEY": "your-api-key" + "CUA_MODEL_NAME": "huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B" } } } @@ -142,10 +150,7 @@ The server is configured using environment variables (can be set in the Claude D | Variable | Description | Default | |----------|-------------|---------| -| `CUA_AGENT_LOOP` | Agent loop to use (OPENAI, ANTHROPIC, UITARS, OMNI) | OMNI | -| `CUA_MODEL_PROVIDER` | Model provider (ANTHROPIC, OPENAI, OLLAMA, OAICOMPAT) | ANTHROPIC | -| `CUA_MODEL_NAME` | Model name to use | None (provider default) | -| `CUA_PROVIDER_BASE_URL` | Base URL for provider API | None | +| `CUA_MODEL_NAME` | Model string (e.g., "anthropic/claude-3-5-sonnet-20241022", "openai/computer-use-preview", "huggingface-local/ByteDance-Seed/UI-TARS-1.5-7B", "omniparser+litellm/gpt-4o", "omniparser+ollama_chat/gemma3") | anthropic/claude-3-5-sonnet-20241022 | | `CUA_MAX_IMAGES` | Maximum number of images to keep in context | 3 | ## Available Tools diff --git a/libs/python/mcp-server/mcp_server/server.py b/libs/python/mcp-server/mcp_server/server.py index 03971cb6..73996d5e 100644 --- a/libs/python/mcp-server/mcp_server/server.py +++ b/libs/python/mcp-server/mcp_server/server.py @@ -3,6 +3,7 @@ import base64 import logging import os import sys +from tabnanny import verbose import traceback from typing import Any, Dict, List, Optional, Union, Tuple @@ -28,7 +29,7 @@ except ImportError as e: try: from computer import Computer - from agent import ComputerAgent, LLMProvider, LLM, AgentLoop + from agent import ComputerAgent logger.debug("Successfully imported Computer and Agent modules") except ImportError as e: @@ -92,49 +93,27 @@ def serve() -> FastMCP: global_computer = Computer(verbosity=logging.INFO) await global_computer.run() - # Determine which loop to use - loop_str = os.getenv("CUA_AGENT_LOOP", "OMNI") - loop = getattr(AgentLoop, loop_str) + # Get model name - this now determines the loop and provider + model_name = os.getenv("CUA_MODEL_NAME", "anthropic/claude-3-5-sonnet-20241022") + + logger.info(f"Using model: {model_name}") - # Determine provider - provider_str = os.getenv("CUA_MODEL_PROVIDER", "ANTHROPIC") - provider = getattr(LLMProvider, provider_str) - - # Get model name (if specified) - model_name = os.getenv("CUA_MODEL_NAME", None) - - # Get base URL for provider (if needed) - provider_base_url = os.getenv("CUA_PROVIDER_BASE_URL", None) - - # Get api key for provider (if needed) - api_key = os.getenv("CUA_PROVIDER_API_KEY", None) - - # Create agent with the specified configuration + # Create agent with the new v0.4.x API agent = ComputerAgent( - computer=global_computer, - loop=loop, - model=LLM( - provider=provider, - name=model_name, - provider_base_url=provider_base_url, - ), - api_key=api_key, - save_trajectory=False, + model=model_name, only_n_most_recent_images=int(os.getenv("CUA_MAX_IMAGES", "3")), verbosity=logging.INFO, + tools=[global_computer] ) + # Create messages in the new v0.4.x format + messages = [{"role": "user", "content": task}] + # Collect all results full_result = "" - async for result in agent.run(task): - logger.info(f"Agent step complete: {result.get('id', 'unknown')}") - ctx.info(f"Agent step complete: {result.get('id', 'unknown')}") - - # Add response ID to output - full_result += f"\n[Response ID: {result.get('id', 'unknown')}]\n" - - if "content" in result: - full_result += f"Response: {result.get('content', '')}\n" + async for result in agent.run(messages): + logger.info(f"Agent processing step") + ctx.info(f"Agent processing step") # Process output if available outputs = result.get("output", []) @@ -145,25 +124,23 @@ def serve() -> FastMCP: content = output.get("content", []) for content_part in content: if content_part.get("text"): - full_result += f"\nMessage: {content_part.get('text', '')}\n" - elif output_type == "reasoning": - logger.debug(f"Reasoning: {output}") - - summary_content = output.get("summary", []) - if summary_content: - for summary_part in summary_content: - if summary_part.get("text"): - full_result += f"\nReasoning: {summary_part.get('text', '')}\n" + full_result += f"Message: {content_part.get('text', '')}\n" + elif output_type == "tool_use": + logger.debug(f"Tool use: {output}") + tool_name = output.get("name", "") + full_result += f"Tool: {tool_name}\n" + elif output_type == "tool_result": + logger.debug(f"Tool result: {output}") + result_content = output.get("content", "") + if isinstance(result_content, list): + for item in result_content: + if item.get("type") == "text": + full_result += f"Result: {item.get('text', '')}\n" else: - full_result += f"\nReasoning: {output.get('text', output.get('content', ''))}\n" - elif output_type == "computer_call": - logger.debug(f"Computer call: {output}") - action = output.get("action", "") - result_value = output.get("result", "") - full_result += f"\nComputer Action: {action}\nResult: {result_value}\n" + full_result += f"Result: {result_content}\n" # Add separator between steps - full_result += "\n" + "-" * 40 + "\n" + full_result += "\n" + "-" * 20 + "\n" logger.info(f"CUA task completed successfully") ctx.info(f"CUA task completed successfully") @@ -179,7 +156,21 @@ def serve() -> FastMCP: error_msg = f"Error running CUA task: {str(e)}\n{traceback.format_exc()}" logger.error(error_msg) ctx.error(error_msg) - return f"Error during task execution: {str(e)}" + # Return tuple with error message and a screenshot if possible + try: + if global_computer is not None: + screenshot = await global_computer.interface.screenshot() + return ( + f"Error during task execution: {str(e)}", + Image(format="png", data=screenshot) + ) + except: + pass + # If we can't get a screenshot, return a placeholder + return ( + f"Error during task execution: {str(e)}", + Image(format="png", data=b"") + ) @server.tool() async def run_multi_cua_tasks(ctx: Context, tasks: List[str]) -> List: diff --git a/libs/python/mcp-server/pyproject.toml b/libs/python/mcp-server/pyproject.toml index ed2ad435..f80a1b6b 100644 --- a/libs/python/mcp-server/pyproject.toml +++ b/libs/python/mcp-server/pyproject.toml @@ -13,8 +13,8 @@ authors = [ ] dependencies = [ "mcp>=1.6.0,<2.0.0", - "cua-agent[all]>=0.3.0,<0.4.0", - "cua-computer>=0.3.0,<0.4.0", + "cua-agent[all]>=0.4.0,<0.5.0", + "cua-computer>=0.4.0,<0.5.0", ] [project.scripts] diff --git a/libs/typescript/README.md b/libs/typescript/README.md index 78fda2e7..9474f49d 100644 --- a/libs/typescript/README.md +++ b/libs/typescript/README.md @@ -1,6 +1,6 @@ -# C/UA TypeScript Libraries +# CUA TypeScript Libraries -This repository contains TypeScript implementations of the C/UA libraries: +This repository contains TypeScript implementations of the CUA libraries: - `@trycua/core`: Core functionality including telemetry and logging - `@trycua/computer`: Computer interaction SDK for VM management and control @@ -90,7 +90,7 @@ pnpm lint:fix:all ### @trycua/core -Core functionality for C/UA libraries including: +Core functionality for CUA libraries including: - Telemetry with PostHog integration - Common utilities and types diff --git a/libs/typescript/computer/LICENSE b/libs/typescript/computer/LICENSE index 7ff04379..0d9333db 100644 --- a/libs/typescript/computer/LICENSE +++ b/libs/typescript/computer/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright © 2025 C/UA +Copyright © 2025 CUA Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libs/typescript/computer/README.md b/libs/typescript/computer/README.md index a9d42740..b51713c2 100644 --- a/libs/typescript/computer/README.md +++ b/libs/typescript/computer/README.md @@ -1,4 +1,4 @@ -# C/ua Computer TypeScript Library +# Cua Computer TypeScript Library The TypeScript library for C/cua Computer - a powerful computer control and automation library. @@ -87,4 +87,4 @@ pnpm typecheck ## License -[MIT](./LICENSE) License 2025 [C/UA](https://github.com/trycua) +[MIT](./LICENSE) License 2025 [CUA](https://github.com/trycua) diff --git a/libs/typescript/computer/package.json b/libs/typescript/computer/package.json index ba9c0934..b9d3b76e 100644 --- a/libs/typescript/computer/package.json +++ b/libs/typescript/computer/package.json @@ -2,7 +2,7 @@ "name": "@trycua/computer", "version": "0.1.3", "packageManager": "pnpm@10.11.0", - "description": "Typescript SDK for c/ua computer interaction", + "description": "Typescript SDK for cua computer interaction", "type": "module", "license": "MIT", "homepage": "https://github.com/trycua/cua/tree/feature/computer/typescript/libs/typescript/computer", @@ -13,7 +13,7 @@ "type": "git", "url": "git+https://github.com/trycua/cua.git" }, - "author": "c/ua", + "author": "cua", "files": [ "dist" ], diff --git a/libs/typescript/core/LICENSE b/libs/typescript/core/LICENSE index 74987166..93914d8b 100644 --- a/libs/typescript/core/LICENSE +++ b/libs/typescript/core/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright © 2025 C/ua +Copyright © 2025 Cua Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libs/typescript/core/README.md b/libs/typescript/core/README.md index 20a77b26..bc585ce8 100644 --- a/libs/typescript/core/README.md +++ b/libs/typescript/core/README.md @@ -1,6 +1,6 @@ -# C/ua Core TypeScript Library +# Cua Core TypeScript Library -The core c/ua library with support for telemetry and other utilities. +The core cua library with support for telemetry and other utilities. ## Development @@ -24,4 +24,4 @@ pnpm build ## License -[MIT](./LICENSE) License 2025 [C/UA](https://github.com/trycua) +[MIT](./LICENSE) License 2025 [CUA](https://github.com/trycua) diff --git a/libs/typescript/core/package.json b/libs/typescript/core/package.json index d15d4138..21b592d9 100644 --- a/libs/typescript/core/package.json +++ b/libs/typescript/core/package.json @@ -2,7 +2,7 @@ "name": "@trycua/core", "version": "0.1.3", "packageManager": "pnpm@10.11.0", - "description": "Typescript SDK for c/ua core.", + "description": "Typescript SDK for cua core.", "type": "module", "license": "MIT", "homepage": "https://github.com/trycua/cua/tree/feature/computer/typescript/libs/typescript/computer", @@ -13,7 +13,7 @@ "type": "git", "url": "git+https://github.com/trycua/cua.git" }, - "author": "c/ua", + "author": "cua", "files": [ "dist" ], diff --git a/libs/typescript/package.json b/libs/typescript/package.json index 0e0d6ce1..76d313ec 100644 --- a/libs/typescript/package.json +++ b/libs/typescript/package.json @@ -1,9 +1,9 @@ { "name": "cua-ts", "version": "1.0.0", - "description": "The c/ua typescript libs.", + "description": "The cua typescript libs.", "keywords": [], - "author": "c/ua", + "author": "cua", "license": "MIT", "scripts": { "lint": "biome check", diff --git a/notebooks/agent_nb.ipynb b/notebooks/agent_nb.ipynb index ead27655..61e7288a 100644 --- a/notebooks/agent_nb.ipynb +++ b/notebooks/agent_nb.ipynb @@ -6,7 +6,7 @@ "source": [ "## Agent\n", "\n", - "This notebook demonstrates how to use Cua's Agent to run workflows in virtual sandboxes, either using C/ua Cloud Containers or local VMs on Apple Silicon Macs." + "This notebook demonstrates how to use Cua's Agent to run workflows in virtual sandboxes, either using Cua Cloud Containers or local VMs on Apple Silicon Macs." ] }, { @@ -103,7 +103,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Option 1: Agent with C/ua Cloud Containers\n", + "## Option 1: Agent with Cua Cloud Containers\n", "\n", "Use cloud containers for running agents from any system without local setup." ] @@ -114,7 +114,7 @@ "source": [ "### Prerequisites for Cloud Containers\n", "\n", - "To use C/ua Cloud Containers, you need to:\n", + "To use Cua Cloud Containers, you need to:\n", "1. Sign up at https://trycua.com\n", "2. Create a Cloud Container\n", "3. Generate an API Key\n", @@ -126,7 +126,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Get C/ua API credentials and container details" + "Get Cua API credentials and container details" ] }, { @@ -136,7 +136,7 @@ "outputs": [], "source": [ "cua_api_key = os.getenv(\"CUA_API_KEY\") or \\\n", - " input(\"Enter your C/ua API Key: \")\n", + " input(\"Enter your Cua API Key: \")\n", "container_name = os.getenv(\"CONTAINER_NAME\") or \\\n", " input(\"Enter your Cloud Container name: \")" ] @@ -379,7 +379,7 @@ "metadata": {}, "outputs": [], "source": [ - "from agent.ui.gradio.app import create_gradio_ui\n", + "from agent.ui.gradio.ui_components import create_gradio_ui\n", "\n", "app = create_gradio_ui()\n", "app.launch(share=False)" diff --git a/notebooks/blog/build-your-own-operator-on-macos-2.ipynb b/notebooks/blog/build-your-own-operator-on-macos-2.ipynb index 52bfd883..ba039bfe 100644 --- a/notebooks/blog/build-your-own-operator-on-macos-2.ipynb +++ b/notebooks/blog/build-your-own-operator-on-macos-2.ipynb @@ -85,7 +85,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Running a c/ua Agent" + "## Running a cua Agent" ] }, { diff --git a/notebooks/computer_nb.ipynb b/notebooks/computer_nb.ipynb index c95d37f2..d1d97d12 100644 --- a/notebooks/computer_nb.ipynb +++ b/notebooks/computer_nb.ipynb @@ -6,7 +6,7 @@ "source": [ "## Computer\n", "\n", - "This notebook demonstrates how to use Computer to operate sandbox VMs programmatically, either using C/ua Cloud Containers or local Lume VMs on Apple Silicon macOS systems." + "This notebook demonstrates how to use Computer to operate sandbox VMs programmatically, either using Cua Cloud Containers or local Lume VMs on Apple Silicon macOS systems." ] }, { @@ -53,9 +53,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Option 1: C/ua Cloud Containers\n", + "## Option 1: Cua Cloud Containers\n", "\n", - "C/ua Cloud Containers provide remote VMs that can be accessed from any system without local setup." + "Cua Cloud Containers provide remote VMs that can be accessed from any system without local setup." ] }, { @@ -64,7 +64,7 @@ "source": [ "### Prerequisites for Cloud Containers\n", "\n", - "To use C/ua Cloud Containers, you need to:\n", + "To use Cua Cloud Containers, you need to:\n", "1. Sign up at https://trycua.com\n", "2. Create a Cloud Container\n", "3. Generate an API Key\n", @@ -82,7 +82,7 @@ "import os\n", "\n", "cua_api_key = os.getenv(\"CUA_API_KEY\") or \\\n", - " input(\"Enter your C/ua API Key: \")\n", + " input(\"Enter your Cua API Key: \")\n", "container_name = os.getenv(\"CONTAINER_NAME\") or \\\n", " input(\"Enter your Cloud Container name: \")" ] @@ -123,7 +123,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Connect to your existing C/ua Cloud Container" + "Connect to your existing Cua Cloud Container" ] }, { diff --git a/scripts/playground-docker.sh b/scripts/playground-docker.sh index 61b57901..5cfae574 100644 --- a/scripts/playground-docker.sh +++ b/scripts/playground-docker.sh @@ -26,13 +26,13 @@ print_warning() { echo -e "${YELLOW}==> $1${NC}" } -echo "🚀 Launching C/ua Computer-Use Agent UI..." +echo "🚀 Launching Cua Computer-Use Agent UI..." # Check if Docker is installed if ! command -v docker &> /dev/null; then print_error "Docker is not installed!" echo "" - echo "To use C/ua with Docker containers, you need to install Docker first:" + echo "To use Cua with Docker containers, you need to install Docker first:" echo "" echo "📦 Install Docker:" echo " • macOS: Download Docker Desktop from https://docker.com/products/docker-desktop" @@ -63,7 +63,7 @@ mkdir -p "$DEMO_DIR" # Check if we're already in the cua repository # Look for the specific trycua identifier in pyproject.toml if [[ -f "pyproject.toml" ]] && grep -q "gh@trycua.com" "pyproject.toml"; then - print_success "Already in C/ua repository - using current directory" + print_success "Already in Cua repository - using current directory" REPO_DIR="$ORIGINAL_DIR" USE_EXISTING_REPO=true else @@ -79,17 +79,17 @@ cleanup() { trap cleanup EXIT echo "" -echo "Choose your C/ua setup:" -echo "1) ☁️ C/ua Cloud Containers (works on any system)" +echo "Choose your Cua setup:" +echo "1) ☁️ Cua Cloud Containers (works on any system)" echo "2) 🖥️ Local macOS VMs (requires Apple Silicon Mac + macOS 15+)" echo "3) 🖥️ Local Windows VMs (requires Windows 10 / 11)" echo "" read -p "Enter your choice (1, 2, or 3): " CHOICE if [[ "$CHOICE" == "1" ]]; then - # C/ua Cloud Container setup + # Cua Cloud Container setup echo "" - print_info "Setting up C/ua Cloud Containers..." + print_info "Setting up Cua Cloud Containers..." echo "" # Check if existing .env.local already has CUA_API_KEY @@ -116,15 +116,15 @@ if [[ "$CHOICE" == "1" ]]; then # If no valid API key found, prompt for one if [[ -z "$CUA_API_KEY" ]]; then - echo "To use C/ua Cloud Containers, you need to:" + echo "To use Cua Cloud Containers, you need to:" echo "1. Sign up at https://trycua.com" echo "2. Create a Cloud Container" echo "3. Generate an Api Key" echo "" - read -p "Enter your C/ua Api Key: " CUA_API_KEY + read -p "Enter your Cua Api Key: " CUA_API_KEY if [[ -z "$CUA_API_KEY" ]]; then - print_error "C/ua Api Key is required for Cloud Containers." + print_error "Cua Api Key is required for Cloud Containers." exit 1 fi else @@ -142,7 +142,7 @@ elif [[ "$CHOICE" == "2" ]]; then # Check for Apple Silicon Mac if [[ $(uname -s) != "Darwin" || $(uname -m) != "arm64" ]]; then print_error "Local macOS VMs require an Apple Silicon Mac (M1/M2/M3/M4)." - echo "💡 Consider using C/ua Cloud Containers instead (option 1)." + echo "💡 Consider using Cua Cloud Containers instead (option 1)." exit 1 fi @@ -150,7 +150,7 @@ elif [[ "$CHOICE" == "2" ]]; then OSVERSION=$(sw_vers -productVersion) if [[ $(echo "$OSVERSION 15.0" | tr " " "\n" | sort -V | head -n 1) != "15.0" ]]; then print_error "Local macOS VMs require macOS 15 (Sequoia) or newer. You have $OSVERSION." - echo "💡 Consider using C/ua Cloud Containers instead (option 1)." + echo "💡 Consider using Cua Cloud Containers instead (option 1)." exit 1 fi @@ -165,7 +165,7 @@ elif [[ "$CHOICE" == "3" ]]; then # Check if we're on Windows if [[ $(uname -s) != MINGW* && $(uname -s) != CYGWIN* && $(uname -s) != MSYS* ]]; then print_error "Local Windows VMs require Windows 10 or 11." - echo "💡 Consider using C/ua Cloud Containers instead (option 1)." + echo "💡 Consider using Cua Cloud Containers instead (option 1)." echo "" echo "🔗 If you are using WSL, refer to the blog post to get started: https://www.trycua.com/blog/windows-sandbox" exit 1 @@ -188,11 +188,11 @@ if [[ "$USE_EXISTING_REPO" == "true" ]]; then else # Clone or update the repository if [[ ! -d "$REPO_DIR" ]]; then - print_info "Cloning C/ua repository..." + print_info "Cloning Cua repository..." cd "$DEMO_DIR" git clone https://github.com/trycua/cua.git else - print_info "Updating C/ua repository..." + print_info "Updating Cua repository..." cd "$REPO_DIR" git pull origin main fi @@ -303,9 +303,9 @@ chmod +x "$DEMO_DIR/start_ui.sh" print_success "Setup complete!" if [[ "$USE_CLOUD" == "true" ]]; then - echo "☁️ C/ua Cloud Container setup complete!" + echo "☁️ Cua Cloud Container setup complete!" else - echo "🖥️ C/ua Local VM setup complete!" + echo "🖥️ Cua Local VM setup complete!" fi echo "📝 Edit $ENV_FILE to update your API keys" @@ -313,10 +313,10 @@ echo "🖥️ Start the playground by running: $DEMO_DIR/start_ui.sh" # Start the demo automatically echo -print_info "Starting the C/ua Computer-Use Agent UI..." +print_info "Starting the Cua Computer-Use Agent UI..." echo "" -print_success "C/ua Computer-Use Agent UI is now running at http://localhost:7860/" +print_success "Cua Computer-Use Agent UI is now running at http://localhost:7860/" echo echo "🌐 Open your browser and go to: http://localhost:7860/" echo diff --git a/scripts/playground.sh b/scripts/playground.sh index 9be712d2..0cde5a25 100755 --- a/scripts/playground.sh +++ b/scripts/playground.sh @@ -2,7 +2,7 @@ set -e -echo "🚀 Launching C/ua Computer-Use Agent UI..." +echo "🚀 Launching Cua Computer-Use Agent UI..." # Save the original working directory ORIGINAL_DIR="$(pwd)" @@ -22,18 +22,18 @@ TMP_DIR=$(mktemp -d) cd "$TMP_DIR" trap cleanup EXIT -# Ask user to choose between local macOS VMs or C/ua Cloud Containers +# Ask user to choose between local macOS VMs or Cua Cloud Containers echo "" -echo "Choose your C/ua setup:" -echo "1) ☁️ C/ua Cloud Containers (works on any system)" +echo "Choose your Cua setup:" +echo "1) ☁️ Cua Cloud Containers (works on any system)" echo "2) 🖥️ Local macOS VMs (requires Apple Silicon Mac + macOS 15+)" echo "" read -p "Enter your choice (1 or 2): " CHOICE if [[ "$CHOICE" == "1" ]]; then - # C/ua Cloud Container setup + # Cua Cloud Container setup echo "" - echo "☁️ Setting up C/ua Cloud Containers..." + echo "☁️ Setting up Cua Cloud Containers..." echo "" # Check if existing .env.local already has CUA_API_KEY (check current dir and demo dir) @@ -61,15 +61,15 @@ if [[ "$CHOICE" == "1" ]]; then # If no valid API key found, prompt for one if [[ -z "$CUA_API_KEY" ]]; then - echo "To use C/ua Cloud Containers, you need to:" + echo "To use Cua Cloud Containers, you need to:" echo "1. Sign up at https://trycua.com" echo "2. Create a Cloud Container" echo "3. Generate an Api Key" echo "" - read -p "Enter your C/ua Api Key: " CUA_API_KEY + read -p "Enter your Cua Api Key: " CUA_API_KEY if [[ -z "$CUA_API_KEY" ]]; then - echo "❌ C/ua Api Key is required for Cloud Containers." + echo "❌ Cua Api Key is required for Cloud Containers." exit 1 fi fi @@ -84,7 +84,7 @@ elif [[ "$CHOICE" == "2" ]]; then # Check for Apple Silicon Mac if [[ $(uname -s) != "Darwin" || $(uname -m) != "arm64" ]]; then echo "❌ Local macOS VMs require an Apple Silicon Mac (M1/M2/M3/M4)." - echo "💡 Consider using C/ua Cloud Containers instead (option 1)." + echo "💡 Consider using Cua Cloud Containers instead (option 1)." exit 1 fi @@ -92,7 +92,7 @@ elif [[ "$CHOICE" == "2" ]]; then OSVERSION=$(sw_vers -productVersion) if [[ $(echo "$OSVERSION 15.0" | tr " " "\n" | sort -V | head -n 1) != "15.0" ]]; then echo "❌ Local macOS VMs require macOS 15 (Sequoia) or newer. You have $OSVERSION." - echo "💡 Consider using C/ua Cloud Containers instead (option 1)." + echo "💡 Consider using Cua Cloud Containers instead (option 1)." exit 1 fi @@ -205,7 +205,7 @@ fi source "$VENV_DIR/bin/activate" # Install required packages -echo "📦 Updating C/ua packages..." +echo "📦 Updating Cua packages..." pip install -U pip setuptools wheel Cmake pip install -U cua-computer "cua-agent[all]" @@ -257,7 +257,7 @@ from pathlib import Path from dotenv import load_dotenv from computer import Computer from agent import ComputerAgent, LLM, AgentLoop, LLMProvider -from agent.ui.gradio.app import create_gradio_ui +from agent.ui.gradio.ui_components import create_gradio_ui # Load environment variables from .env.local load_dotenv(Path(__file__).parent / ".env.local") @@ -292,7 +292,7 @@ from pathlib import Path from dotenv import load_dotenv from computer import Computer from agent import ComputerAgent, LLM, AgentLoop, LLMProvider -from agent.ui.gradio.app import create_gradio_ui +from agent.ui.gradio.ui_components import create_gradio_ui # Load environment variables from .env.local load_dotenv(Path(__file__).parent / ".env.local") @@ -336,10 +336,10 @@ fi # Ask if the user wants to start the demo now echo -read -p "Would you like to start the C/ua Computer-Use Agent UI now? (y/n) " -n 1 -r +read -p "Would you like to start the Cua Computer-Use Agent UI now? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "🚀 Starting the C/ua Computer-Use Agent UI..." + echo "🚀 Starting the Cua Computer-Use Agent UI..." echo "" "$DEMO_DIR/start_ui.sh" fi diff --git a/tests/files.py b/tests/files.py index bcfbb4f5..b0ae9c60 100644 --- a/tests/files.py +++ b/tests/files.py @@ -2,7 +2,7 @@ File System Interface Tests Tests for the file system methods of the Computer interface (macOS). Required environment variables: -- CUA_API_KEY: API key for C/ua cloud provider +- CUA_API_KEY: API key for Cua cloud provider - CUA_CONTAINER_NAME: Name of the container to use """ @@ -33,7 +33,7 @@ from computer import Computer, VMProviderType @pytest.fixture(scope="session") async def computer(): """Shared Computer instance for all test cases.""" - # Create a remote Linux computer with C/ua + # Create a remote Linux computer with Cua computer = Computer( os_type="linux", api_key=os.getenv("CUA_API_KEY"), @@ -41,7 +41,7 @@ async def computer(): provider_type=VMProviderType.CLOUD, ) - # Create a local macOS computer with C/ua + # Create a local macOS computer with Cua # computer = Computer() # Connect to host computer diff --git a/tests/shell_bash.py b/tests/shell_bash.py index af34ff0e..ca7f8e1f 100644 --- a/tests/shell_bash.py +++ b/tests/shell_bash.py @@ -2,7 +2,7 @@ Shell Command Tests (Bash) Tests for the run_command method of the Computer interface using bash commands. Required environment variables: -- CUA_API_KEY: API key for C/ua cloud provider +- CUA_API_KEY: API key for Cua cloud provider - CUA_CONTAINER_NAME: Name of the container to use """ @@ -33,7 +33,7 @@ from computer import Computer, VMProviderType @pytest.fixture(scope="session") async def computer(): """Shared Computer instance for all test cases.""" - # Create a remote Linux computer with C/ua + # Create a remote Linux computer with Cua computer = Computer( os_type="linux", api_key=os.getenv("CUA_API_KEY"), diff --git a/tests/shell_cmd.py b/tests/shell_cmd.py index a210e453..6062e53e 100644 --- a/tests/shell_cmd.py +++ b/tests/shell_cmd.py @@ -2,7 +2,7 @@ Shell Command Tests (CMD) Tests for the run_command method of the Computer interface using cmd.exe commands. Required environment variables: -- CUA_API_KEY: API key for C/ua cloud provider +- CUA_API_KEY: API key for Cua cloud provider - CUA_CONTAINER_NAME: Name of the container to use """ @@ -33,7 +33,7 @@ from computer import Computer, VMProviderType @pytest.fixture(scope="session") async def computer(): """Shared Computer instance for all test cases.""" - # Create a remote Windows computer with C/ua + # Create a remote Windows computer with Cua computer = Computer( os_type="windows", api_key=os.getenv("CUA_API_KEY"), diff --git a/tests/venv.py b/tests/venv.py index 522a4727..8479e28f 100644 --- a/tests/venv.py +++ b/tests/venv.py @@ -1,9 +1,9 @@ """ Virtual Environment Testing Module -This module tests the ability to execute python code in a virtual environment within C/ua Containers. +This module tests the ability to execute python code in a virtual environment within Cua Containers. Required environment variables: -- CUA_API_KEY: API key for C/ua cloud provider +- CUA_API_KEY: API key for Cua cloud provider - CUA_CONTAINER_NAME: Name of the container to use """ @@ -36,7 +36,7 @@ from computer.helpers import sandboxed, set_default_computer @pytest.fixture(scope="session") async def computer(): """Shared Computer instance for all test cases.""" - # Create a remote Linux computer with C/ua + # Create a remote Linux computer with Cua computer = Computer( os_type="linux", api_key=os.getenv("CUA_API_KEY"), @@ -44,7 +44,7 @@ async def computer(): provider_type=VMProviderType.CLOUD, ) - # # Create a local macOS computer with C/ua + # # Create a local macOS computer with Cua # computer = Computer() try: diff --git a/tests/watchdog.py b/tests/watchdog.py index 24b268c2..c5a014e6 100644 --- a/tests/watchdog.py +++ b/tests/watchdog.py @@ -2,7 +2,7 @@ Watchdog Recovery Tests Tests for the watchdog functionality to ensure server recovery after hanging commands. Required environment variables: -- CUA_API_KEY: API key for C/ua cloud provider +- CUA_API_KEY: API key for Cua cloud provider - CUA_CONTAINER_NAME: Name of the container to use """ @@ -34,7 +34,7 @@ from computer import Computer, VMProviderType @pytest.fixture(scope="session") async def computer(): """Shared Computer instance for all test cases.""" - # Create a remote Linux computer with C/ua + # Create a remote Linux computer with Cua computer = Computer( os_type="linux", api_key=os.getenv("CUA_API_KEY"),