optimize media; README.md; change structure

update mcp guides; better structure cleanup media update README.md and docs index fix links in setup guide update TOCs and usage

Alessandro committed Feb 10, 2026 at 15:23 UTC a76cd524feff18d72cc375a9e6357b9208d08a02
170 files changed +2342 -5420
README.md
+47 -46
@@ -12,12 +12,9 @@
12 ## Documentation:
13
14 [Introduction](#a-personal-organic-agentic-framework-that-grows-and-learns-with-you) •
15 -[Installation](./docs/getting-started/installation.md) •
16 -[Development](./docs/development/setup.md) •
17 -[WebSocket Infrastructure](./docs/advanced/websockets.md) •
18 -[Connectivity](./docs/advanced/connectivity.md) •
19 -[How to update](./docs/getting-started/installation.md#how-to-update-agent-zero) •
20 -[Documentation](./docs/README.md) •
15 +[Installation](./docs/setup/installation.md) •
16 +[How to update](./docs/setup/installation.md#how-to-update-agent-zero) <br>
17 +[Development Setup](./docs/setup/dev-setup.md) •
18 [Usage](./docs/guides/usage.md)
19
20 Or see DeepWiki generated documentation:
@@ -29,8 +26,12 @@ Or see DeepWiki generated documentation:
26
27 <div align="center">
28
32 -> ### 🚨 **PROJECTS!** 🚨
33 -> Agent Zero now supports **Projects** – isolated workspaces with their own prompts, files, memory, and secrets, so you can create dedicated setups for each use case without mixing contexts.
29 +> ### 🚨 **AGENT ZERO SKILLS** 🚨
30 +> Agent Zero Instruments become **Skills** - portable, structured agent capabilities using the open `SKILL.md` standard (compatible with Claude Code, Codex and more).
31 +>
32 +> **Plus:** Git-based Projects with authentication for public/private repositories - clone codebases directly into isolated workspaces.
33 +>
34 +> See [Usage Guide](./docs/guides/usage.md) and [Projects Tutorial](./docs/guides/projects.md) to get started.
35 </div>
36
37
@@ -46,6 +47,26 @@ Or see DeepWiki generated documentation:
47 - Agent Zero is fully transparent, readable, comprehensible, customizable, and interactive.
48 - Agent Zero uses the computer as a tool to accomplish its (your) tasks.
49
50 +# ⚙️ Installation
51 +
52 +Click to open a video to learn how to install Agent Zero:
53 +
54 +[![Easy Installation guide](/docs/res/easy_ins_vid.png)](https://www.youtube.com/watch?v=w5v5Kjx51hs)
55 +
56 +A detailed setup guide for Windows, macOS, and Linux with a video can be found in the Agent Zero Documentation at [this page](./docs/setup/installation.md).
57 +
58 +### ⚡ Quick Start
59 +
60 +```bash
61 +# Pull and run with Docker
62 +
63 +docker pull agent0ai/agent-zero
64 +docker run -p 50001:80 agent0ai/agent-zero
65 +
66 +# Visit http://localhost:50001 to start
67 +```
68 +
69 +
70 # 💡 Key Features
71
72 1. **General-purpose Assistant**
@@ -53,7 +74,7 @@ Or see DeepWiki generated documentation:
74 - Agent Zero is not pre-programmed for specific tasks (but can be). It is meant to be a general-purpose personal assistant. Give it a task, and it will gather information, execute commands and code, cooperate with other agent instances, and do its best to accomplish it.
75 - It has a persistent memory, allowing it to memorize previous solutions, code, facts, instructions, etc., to solve tasks faster and more reliably in the future.
76
56 -![Agent 0 Working](/docs/res/ui-screen-2.png)
77 +![Agent 0 Working](/docs/res/ui_screen2.png)
78
79 2. **Computer as a Tool**
80
@@ -70,8 +91,7 @@ Or see DeepWiki generated documentation:
91 - In the case of the first agent in the chain (Agent 0), the superior is the human user; the agent sees no difference.
92 - Every agent can create its subordinate agent to help break down and solve subtasks. This helps all agents keep their context clean and focused.
93
73 -![Multi-agent](docs/res/physics.png)
74 -![Multi-agent 2](docs/res/physics-2.png)
94 +![Multi-agent](docs/res/usage/multi-agent.png)
95
96 4. **Completely Customizable and Extensible**
97
@@ -82,7 +102,7 @@ Or see DeepWiki generated documentation:
102 - Every default tool can be found in the **python/tools/** folder and changed or copied to create new predefined tools.
103 - **Automated configuration** via `A0_SET_` environment variables for deployment automation and easy setup.
104
85 -![Prompts](/docs/res/prompts.png)
105 +![Prompts](/docs/res/profiles.png)
106
107 5. **Communication is Key**
108
@@ -91,41 +111,21 @@ Or see DeepWiki generated documentation:
111 - The terminal interface is real-time streamed and interactive. You can stop and intervene at any point. If you see your agent heading in the wrong direction, just stop and tell it right away.
112 - There is a lot of freedom in this framework. You can instruct your agents to regularly report back to superiors asking for permission to continue. You can instruct them to use point-scoring systems when deciding when to delegate subtasks. Superiors can double-check subordinates' results and dispute. The possibilities are endless.
113
94 -## 🚀 Things you can build with Agent Zero
114 +## 🚀 Real-world use cases
115
96 -- **Development Projects** - `"Create a React dashboard with real-time data visualization"`
116 +- **Financial Analysis & Charting** - `"Find last month's Bitcoin/USD price trend, correlate with major cryptocurrency news events, generate annotated chart with highlighted key dates"`
117
98 -- **Data Analysis** - `"Analyze last quarter's NVIDIA sales data and create trend reports"`
118 +- **Excel Automation Pipeline** - `"Scan incoming directory for financial spreadsheets, validate and clean data, consolidate from multiple sources, generate executive reports with flagged anomalies"`
119
100 -- **Content Creation** - `"Write a technical blog post about microservices"`
120 +- **API Integration Without Code** - `"Use this Google Gemini API snippet to generate product images, remember the integration for future use"` - agent learns and stores the solution in memory
121
102 -- **System Admin** - `"Set up a monitoring system for our web servers"`
122 +- **Automated Server Monitoring** - `"Check server status every 30 minutes: CPU usage, disk space, memory. Alert if metrics exceed thresholds"` (scheduled task with project-scoped credentials)
123
104 -- **Research** - `"Gather and summarize five recent AI papers about CoT prompting"`
105 -
106 -
107 -# ⚙️ Installation
108 -
109 -Click to open a video to learn how to install Agent Zero:
110 -
111 -[![Easy Installation guide](/docs/res/easy_ins_vid.png)](https://www.youtube.com/watch?v=w5v5Kjx51hs)
112 -
113 -A detailed setup guide for Windows, macOS, and Linux with a video can be found in the Agent Zero Documentation at [this page](./docs/getting-started/installation.md).
114 -
115 -### ⚡ Quick Start
116 -
117 -```bash
118 -# Pull and run with Docker
119 -
120 -docker pull agent0ai/agent-zero
121 -docker run -p 50001:80 agent0ai/agent-zero
122 -
123 -# Visit http://localhost:50001 to start
124 -```
124 +- **Multi-Client Project Isolation** - Separate projects for each client with isolated memory, custom instructions, and dedicated secrets - prevents context bleed across sensitive work
125
126 ## 🐳 Fully Dockerized, with Speech-to-Text and TTS
127
128 -![Settings](docs/res/settings-page-ui.png)
128 +![Settings](docs/res/settings-page-ui1.png)
129
130 - Customizable settings allow users to tailor the agent's behavior and responses to their needs.
131 - The Web UI output is very clean, fluid, colorful, readable, and interactive; nothing is hidden.
@@ -153,14 +153,15 @@ docker run -p 50001:80 agent0ai/agent-zero
153
154 | Page | Description |
155 |-------|-------------|
156 -| [Installation](./docs/getting-started/installation.md) | Installation, setup and configuration |
156 +| [Installation](./docs/setup/installation.md) | Installation, setup and configuration |
157 | [Usage](./docs/guides/usage.md) | Basic and advanced usage |
158 -| [Development](./docs/development/setup.md) | Development and customization |
159 -| [WebSocket Infrastructure](./docs/advanced/websockets.md) | Real-time WebSocket handlers, client APIs, filtering semantics, envelopes |
160 -| [Extensibility](./docs/development/extensibility.md) | Extending Agent Zero |
161 -| [Connectivity](./docs/advanced/connectivity.md) | External API endpoints, MCP server connections, A2A protocol |
162 -| [Architecture](./docs/advanced/architecture.md) | System design and components |
163 -| [Contributing](./docs/development/contribution.md) | How to contribute |
158 +| [Guides](./docs/guides/) | Step-by-step guides: Usage, Projects, API Integration, MCP Setup, A2A Setup |
159 +| [Development Setup](./docs/setup/dev-setup.md) | Development and customization |
160 +| [WebSocket Infrastructure](./docs/developer/websockets.md) | Real-time WebSocket handlers, client APIs, filtering semantics, envelopes |
161 +| [Extensions](./docs/developer/extensions.md) | Extending Agent Zero |
162 +| [Connectivity](./docs/developer/connectivity.md) | External API endpoints, MCP server connections, A2A protocol |
163 +| [Architecture](./docs/developer/architecture.md) | System design and components |
164 +| [Contributing](./docs/guides/contribution.md) | How to contribute |
165 | [Troubleshooting](./docs/guides/troubleshooting.md) | Common issues and their solutions |
166
167
docs/README.md new
+120
@@ -0,0 +1,120 @@
1 +![Agent Zero Logo](res/header.png)
2 +# Agent Zero Documentation
3 +
4 +Welcome to the Agent Zero documentation hub. Whether you're getting started or diving deep into the framework, you'll find comprehensive guides below.
5 +
6 +## Quick Start
7 +
8 +- **[Quickstart Guide](quickstart.md):** Get up and running in 5 minutes with Agent Zero.
9 +- **[Installation Guide](setup/installation.md):** Detailed setup instructions for all platforms (or [update your installation](setup/installation.md#how-to-update-agent-zero)).
10 +- **[VPS Deployment](setup/vps-deployment.md):** Deploy Agent Zero on a remote server.
11 +- **[Development Setup](setup/dev-setup.md):** Set up a local development environment.
12 +
13 +## User Guides
14 +
15 +- **[Usage Guide](guides/usage.md):** Comprehensive guide to Agent Zero's features and capabilities.
16 +- **[Projects Tutorial](guides/projects.md):** Learn to create isolated workspaces with dedicated context and memory.
17 +- **[API Integration](guides/api-integration.md):** Add external APIs without writing code.
18 +- **[MCP Setup](guides/mcp-setup.md):** Configure Model Context Protocol servers.
19 +- **[A2A Setup](guides/a2a-setup.md):** Enable agent-to-agent communication.
20 +- **[Troubleshooting](guides/troubleshooting.md):** Solutions to common issues and FAQs.
21 +
22 +## Developer Documentation
23 +
24 +- **[Architecture Overview](developer/architecture.md):** Understand Agent Zero's internal structure and components.
25 +- **[Extensions](developer/extensions.md):** Create custom extensions to extend functionality.
26 +- **[Connectivity](developer/connectivity.md):** Connect to Agent Zero from external applications.
27 +- **[WebSockets](developer/websockets.md):** Real-time communication infrastructure.
28 +- **[MCP Configuration](developer/mcp-configuration.md):** Advanced MCP server configuration.
29 +- **[Notifications](developer/notifications.md):** Notification system architecture and setup.
30 +- **[Contributing Skills](developer/contributing-skills.md):** Create and share agent skills.
31 +- **[Contributing Guide](guides/contribution.md):** Contribute to the Agent Zero project.
32 +
33 +## Community & Support
34 +
35 +- **Join the Community:** Connect with other users on [Discord](https://discord.gg/B8KZKNsPpj) to discuss ideas, ask questions, and collaborate.
36 +- **Share Your Work:** Show off your Agent Zero creations and workflows in the [Show and Tell](https://github.com/agent0ai/agent-zero/discussions/categories/show-and-tell) area.
37 +- **Report Issues:** Use the [GitHub issue tracker](https://github.com/agent0ai/agent-zero/issues) to report bugs or suggest features.
38 +- **Follow Updates:** Subscribe to the [YouTube channel](https://www.youtube.com/@AgentZeroFW) for tutorials and release videos.
39 +
40 +---
41 +
42 +## Table of Contents
43 +
44 +- [Quick Start](#quick-start)
45 + - [Quickstart Guide](quickstart.md)
46 + - [Installation Guide](setup/installation.md)
47 + - [Step 1: Install Docker Desktop](setup/installation.md#step-1-install-docker-desktop)
48 + - [Windows Installation](setup/installation.md#-windows-installation)
49 + - [macOS Installation](setup/installation.md#-macos-installation)
50 + - [Linux Installation](setup/installation.md#-linux-installation)
51 + - [Step 2: Run Agent Zero](setup/installation.md#step-2-run-agent-zero)
52 + - [Pull Docker Image](setup/installation.md#21-pull-the-agent-zero-docker-image)
53 + - [Map Folders for Persistence](setup/installation.md#22-optional-map-folders-for-persistence)
54 + - [Run the Container](setup/installation.md#23-run-the-container)
55 + - [Access the Web UI](setup/installation.md#24-access-the-web-ui)
56 + - [Step 3: Configure Agent Zero](setup/installation.md#step-3-configure-agent-zero)
57 + - [Settings Configuration](setup/installation.md#settings-configuration)
58 + - [Agent Configuration](setup/installation.md#agent-configuration)
59 + - [Chat Model Settings](setup/installation.md#chat-model-settings)
60 + - [API Keys](setup/installation.md#api-keys)
61 + - [Authentication](setup/installation.md#authentication)
62 + - [Choosing Your LLMs](setup/installation.md#choosing-your-llms)
63 + - [Installing Ollama (Local Models)](setup/installation.md#installing-and-using-ollama-local-models)
64 + - [Using on Mobile Devices](setup/installation.md#using-agent-zero-on-your-mobile-device)
65 + - [How to Update Agent Zero](setup/installation.md#how-to-update-agent-zero)
66 + - [VPS Deployment](setup/vps-deployment.md)
67 + - [Development Setup](setup/dev-setup.md)
68 +
69 +- [User Guides](#user-guides)
70 + - [Usage Guide](guides/usage.md)
71 + - [Basic Operations](guides/usage.md#basic-operations)
72 + - [Tool Usage](guides/usage.md#tool-usage)
73 + - [Projects](guides/usage.md#projects)
74 + - [What Projects Provide](guides/usage.md#what-projects-provide)
75 + - [Creating Projects](guides/usage.md#creating-projects)
76 + - [Project Configuration](guides/usage.md#project-configuration)
77 + - [Activating Projects](guides/usage.md#activating-projects)
78 + - [Common Use Cases](guides/usage.md#common-use-cases)
79 + - [Tasks & Scheduling](guides/usage.md#tasks--scheduling)
80 + - [Task Types](guides/usage.md#task-types)
81 + - [Creating Tasks](guides/usage.md#creating-tasks)
82 + - [Task Configuration](guides/usage.md#task-configuration)
83 + - [Integration with Projects](guides/usage.md#integration-with-projects)
84 + - [Secrets & Variables](guides/usage.md#secrets--variables)
85 + - [Remote Access via Tunneling](guides/usage.md#remote-access-via-tunneling)
86 + - [Voice Interface](guides/usage.md#voice-interface)
87 + - [Memory Management](guides/usage.md#memory-management)
88 + - [Backup & Restore](guides/usage.md#backup--restore)
89 + - [Projects Tutorial](guides/projects.md)
90 + - [API Integration](guides/api-integration.md)
91 + - [MCP Setup](guides/mcp-setup.md)
92 + - [A2A Setup](guides/a2a-setup.md)
93 + - [Troubleshooting](guides/troubleshooting.md)
94 +
95 +- [Developer Documentation](#developer-documentation)
96 + - [Architecture Overview](developer/architecture.md)
97 + - [System Architecture](developer/architecture.md#system-architecture)
98 + - [Runtime Architecture](developer/architecture.md#runtime-architecture)
99 + - [Implementation Details](developer/architecture.md#implementation-details)
100 + - [Core Components](developer/architecture.md#core-components)
101 + - [Agents](developer/architecture.md#1-agents)
102 + - [Tools](developer/architecture.md#2-tools)
103 + - [Memory System](developer/architecture.md#3-memory-system)
104 + - [Prompts](developer/architecture.md#4-prompts)
105 + - [Knowledge](developer/architecture.md#5-knowledge)
106 + - [Skills](developer/architecture.md#6-skills)
107 + - [Extensions](developer/architecture.md#7-extensions)
108 + - [Extensions](developer/extensions.md)
109 + - [Connectivity](developer/connectivity.md)
110 + - [WebSockets](developer/websockets.md)
111 + - [MCP Configuration](developer/mcp-configuration.md)
112 + - [Notifications](developer/notifications.md)
113 + - [Contributing Skills](developer/contributing-skills.md)
114 + - [Contributing Guide](guides/contribution.md)
115 +
116 +---
117 +
118 +### Your journey with Agent Zero starts now!
119 +
120 +Ready to dive in? Start with the [Quickstart Guide](quickstart.md) for the fastest path to your first chat, or follow the [Installation Guide](setup/installation.md) for a detailed setup walkthrough.
docs/advanced/tunneling.md deleted
-57
@@ -1,57 +0,0 @@
1 -# Agent Zero Tunnel Feature
2 -
3 -The tunnel feature in Agent Zero allows you to expose your local Agent Zero instance to the internet using Flaredantic tunnels. This makes it possible to share your Agent Zero instance with others without requiring them to install and run Agent Zero themselves.
4 -
5 -## How It Works
6 -
7 -Agent Zero uses the [Flaredantic](https://pypi.org/project/flaredantic/) library to create secure tunnels to expose your local instance to the internet. These tunnels:
8 -
9 -- Are secure (HTTPS)
10 -- Don't require any configuration
11 -- Generate unique URLs for each session
12 -- Can be regenerated on demand
13 -
14 -## Using the Tunnel Feature
15 -
16 -1. Open the settings and navigate to the "External Services" tab
17 -2. Click on "Flare Tunnel" in the navigation menu
18 -3. Click the "Create Tunnel" button to generate a new tunnel
19 -4. Once created, the tunnel URL will be displayed and can be copied to share with others
20 -5. The tunnel URL will remain active until you stop the tunnel or close the Agent Zero application
21 -
22 -## Security Considerations
23 -
24 -When sharing your Agent Zero instance via a tunnel:
25 -
26 -- Anyone with the URL can access your Agent Zero instance
27 -- No additional authentication is added beyond what your Agent Zero instance already has
28 -- Consider setting up authentication if you're sharing sensitive information
29 -- The tunnel exposes your local Agent Zero instance, not your entire system
30 -
31 -## Troubleshooting
32 -
33 -If you encounter issues with the tunnel feature:
34 -
35 -1. Check your internet connection
36 -2. Try refreshing the tunnel URL
37 -3. Restart Agent Zero
38 -4. Check the console logs for any error messages
39 -
40 -## Adding Authentication
41 -
42 -To add basic authentication to your Agent Zero instance when using tunnels, you can set the following environment variables:
43 -
44 -```
45 -AUTH_LOGIN=your_username
46 -AUTH_PASSWORD=your_password
47 -```
48 -
49 -Alternatively, you can configure the username and password directly in the settings:
50 -
51 -1. Open the settings modal in the Agent Zero UI
52 -2. Navigate to the "External Services" tab
53 -3. Find the "Authentication" section
54 -4. Enter your desired username and password in the "UI Login" and "UI Password" fields
55 -5. Click the "Save" button to apply the changes
56 -
57 -This will require users to enter these credentials when accessing your tunneled Agent Zero instance. When attempting to create a tunnel without authentication configured, Agent Zero will display a security warning.
\ No newline at end of file
docs/developer/architecture.md renamed
+3 -12
@@ -2,9 +2,6 @@
2 Agent Zero is built on a flexible and modular architecture designed for extensibility and customization. This section outlines the key components and the interactions between them.
3
4 ## System Architecture
5 -This simplified diagram illustrates the hierarchical relationship between agents and their interaction with tools, extensions, skills, prompts, memory and knowledge base.
6 -
7 -![Agent Zero Architecture](res/arch-01.svg)
5
6 The user or Agent 0 is at the top of the hierarchy, delegating tasks to subordinate agents, which can further delegate to other agents. Each agent can utilize tools and access the shared assets (prompts, memory, knowledge, extensions and skills) to perform its tasks.
7
@@ -60,7 +57,6 @@ This architecture ensures:
57 | `/webui/css` | Stylesheets |
58 | `/webui/js` | JavaScript modules |
59 | `/webui/public` | Static assets |
63 -| `/work_dir` | Working directory (inside Docker: `/a0/work_dir`) |
60
61 ### Key Files
62 | File | Description |
@@ -75,7 +71,6 @@ This architecture ensures:
71 | `prepare.py` | Environment preparation |
72 | `requirements.txt` | Python dependencies |
73 | `run_ui.py` | Web UI launcher |
78 -| `run_tunnel.py` | Tunnel launcher |
74
75 > [!NOTE]
76 > In the Docker runtime, the framework lives under `/a0` inside the container. Data persists as long as the container exists. For upgrades, prefer **Backup & Restore** instead of mapping the full `/a0` directory.
@@ -100,8 +95,6 @@ Communication flows between agents through messages, which are structured accord
95 #### Interaction Flow
96 A typical interaction flow within Agent Zero might look like this:
97
103 -![Interaction Flow](res/flow-01.svg)
104 -
98 1. The user provides an instruction to Agent 0
99 2. Agent 0 initializes VectorDB and access memory
100 3. Agent 0 analyzes the instruction and formulates a plan using `thoughts` argument, possibly involving the use of tools or the creation of sub-agents
@@ -145,7 +138,7 @@ In cases where SearXNG might not return satisfactory results, Agent Zero can be
138 #### Custom Tools
139 Users can create custom tools to extend Agent Zero's capabilities. Custom tools can be integrated into the framework by defining a tool specification, which includes the tool's prompt. Place these prompt overrides in your agent profile:
140
148 -1. Create `agent.system.tool.$TOOL_NAME.md` in `agents/<agent_profile>/prompts/` (or in `prompts/` for global defaults)
141 +1. Create `agent.system.tool.$TOOL_NAME.md` in `agents/<agent_profile>/prompts/`
142 2. Add the reference in `agent.system.tools.md` within the same prompt scope
143 3. If needed, implement tool class in `python/tools` using `Tool` base class
144 4. Follow existing patterns for consistency
@@ -225,7 +218,7 @@ The `prompts` directory contains various Markdown files that control agent behav
218 - **Tool Prompts**: Organized in tool-specific files for modularity
219
220 #### Custom Prompts (Post v0.9.7)
228 -1. Create or select an agent profile under `agents/<agent_profile>/`
221 +1. Create or clone an existing agent profile under `agents/<agent_profile>/`
222 2. Add only the prompt files you want to override in `agents/<agent_profile>/prompts/`
223 3. Agent Zero merges these overrides with the default prompts automatically
224 4. Select the **Agent Profile** in Settings to activate the overrides
@@ -247,8 +240,6 @@ The `prompts` directory contains various Markdown files that control agent behav
240 3. New rules are merged with existing ruleset
241 4. Updated behavior is immediately applied
242
250 -![Behavior Adjustment](res/ui-behavior-change-chat.png)
251 -
243 - **Integration with System Prompt**:
244 - Behavior rules are injected at the start of the system prompt
245 - Rules are formatted in a structured markdown format
@@ -348,4 +339,4 @@ Extensions can be found in `python/extensions` directory:
339
340 > [!NOTE]
341 > Consider contributing valuable custom components to the main repository.
351 -> See [Contributing](contribution.md) for more information.
342 +> See [Contributing](../guides/contribution.md) for more information.
docs/developer/connectivity.md renamed
+2 -2
@@ -605,7 +605,7 @@ It provides two endpoint types:
605 - **Streamable HTTP (`/mcp/http/`):** For clients that use streamable HTTP requests.
606
607 > [!NOTE]
608 -> This section describes **Agent Zero as an MCP server**. To configure Agent Zero as an MCP **client** (consuming external tools), see [MCP Setup](mcp_setup.md).
608 +> This section describes **Agent Zero as an MCP server**. To configure Agent Zero as an MCP **client** (consuming external tools), see [MCP Setup](../guides/mcp-setup.md).
609
610 ### Example MCP Server Configuration
611
@@ -686,4 +686,4 @@ When a project is specified:
686 - Maintain strict context separation between agents
687
688 > [!TIP]
689 -> If you need tool access rather than chat delegation, use MCP instead of A2A. See [MCP Setup](mcp_setup.md).
689 +> If you need tool access rather than chat delegation, use MCP instead of A2A. See [MCP Setup](../guides/mcp-setup.md).
docs/developer/contributing-skills.md renamed
-73
@@ -2,17 +2,6 @@
2
3 Welcome to the Agent Zero Skills ecosystem! This guide will help you create, test, and share skills with the community.
4
5 -## Table of Contents
6 -
7 -- [What is a Skill?](#what-is-a-skill)
8 -- [Quick Start](#quick-start)
9 -- [SKILL.md Standard](#skillmd-standard)
10 -- [Creating Your First Skill](#creating-your-first-skill)
11 -- [Best Practices](#best-practices)
12 -- [Testing Skills](#testing-skills)
13 -- [Sharing Skills](#sharing-skills)
14 -- [Community Guidelines](#community-guidelines)
15 -
5 ---
6
7 ## What is a Skill?
@@ -301,28 +290,6 @@ One skill = one expertise area. If your skill is getting too long, split it:
290 3. **Verify Instructions:**
291 Follow your own instructions manually to ensure they work.
292
304 -### Automated Testing
305 -
306 -Create a test file `test_skill.py` in your skill folder:
307 -
308 -```python
309 -"""Tests for my-awesome-skill"""
310 -import pytest
311 -from python.helpers.skills import SkillManager
312 -
313 -def test_skill_loads():
314 - manager = SkillManager()
315 - skill = manager.get_skill("my-awesome-skill")
316 - assert skill is not None
317 - assert skill.name == "my-awesome-skill"
318 -
319 -def test_skill_has_required_fields():
320 - manager = SkillManager()
321 - skill = manager.get_skill("my-awesome-skill")
322 - assert skill.description
323 - assert len(skill.description) > 20
324 -```
325 -
293 ---
294
295 ## Sharing Skills
@@ -399,34 +366,6 @@ my-skills-collection/
366 - Respect licenses of any code you include
367 - Don't include proprietary or copyrighted content
368
402 -### Code of Conduct
403 -
404 -- Be respectful in all interactions
405 -- Provide constructive feedback
406 -- Help newcomers learn
407 -- Report issues responsibly
408 -
409 ----
410 -
411 -## Resources
412 -
413 -### Official Documentation
414 -
415 -- [Agent Zero Documentation](./README.md)
416 -- [Architecture Guide](./architecture.md)
417 -- [Skills System](./architecture.md#skills-system)
418 -
419 -### Community
420 -
421 -- [GitHub Issues](https://github.com/agent0ai/agent-zero/issues)
422 -- [Discussions](https://github.com/agent0ai/agent-zero/discussions)
423 -
424 -### External Resources
425 -
426 -- [Skills Marketplace](https://skillsmp.com)
427 -- [Awesome Agent Skills](https://github.com/skillmatic-ai/awesome-agent-skills)
428 -- [Anthropic Skills Repository](https://github.com/anthropics/skills)
429 -
369 ---
370
371 ## FAQ
@@ -453,16 +392,4 @@ my-skills-collection/
392
393 ---
394
456 -## Example Skills to Learn From
457 -
458 -Check out these well-structured skills in `skills/`:
459 -
460 -- `brainstorming/` - Requirements exploration workflow
461 -- `debugging/` - Systematic debugging methodology
462 -- `tdd/` - Test-driven development process
463 -- `code-review/` - Comprehensive review checklist
464 -- `create-skill/` - Meta-skill for creating new skills
465 -
466 ----
467 -
395 Happy skill building! 🚀
docs/developer/extensions.md renamed
+1 -13
@@ -1,4 +1,4 @@
1 -# Extensibility framework in Agent Zero
1 +# Extensions Framework
2
3 > [!NOTE]
4 > Agent Zero is built with extensibility in mind. It provides a framework for creating custom extensions, agents, skills, and tools that can be used to enhance the functionality of the framework.
@@ -99,18 +99,6 @@ When a tool is called, it goes through the following lifecycle:
99 3. `execute` method (main functionality)
100 4. `after_execution` method
101
102 -### Instruments
103 -Instruments are reusable scripts and procedures stored on disk and indexed in memory. They are **not** always present in the system prompt, making them lighter-weight than tools for specialized workflows.
104 -
105 -- **When to use tools:** core capabilities you want always available in the prompt
106 -- **When to use instruments:** repeatable scripts or procedures that can be recalled on demand
107 -
108 -#### Creating Instruments
109 -1. Create a folder in `instruments/custom/` (no spaces in name)
110 -2. Add a `.md` description file explaining inputs/outputs
111 -3. Add a script (`.sh`, `.py`, etc.) with the implementation
112 -4. Restart or reload so the agent indexes the instrument
113 -
102 ### API Endpoints
103 API endpoints expose Agent Zero functionality to external systems or the user interface. They are modular and can be extended or replaced.
104
docs/developer/mcp-configuration.md new
+404
@@ -0,0 +1,404 @@
1 +# Advanced MCP Configuration
2 +
3 +This guide provides comprehensive technical details for configuring and utilizing external tool providers through the Model Context Protocol (MCP) with Agent Zero. This allows Agent Zero to leverage tools hosted by separate local or remote MCP-compliant servers.
4 +
5 +> [!NOTE]
6 +> For a quick start guide on adding MCP servers through the UI, see [MCP Setup](../guides/mcp-setup.md).
7 +
8 +> [!NOTE]
9 +> This guide covers Agent Zero as an MCP **client**. To expose Agent Zero as an MCP **server**, see [Connectivity → MCP Server](connectivity.md#mcp-server-connectivity).
10 +
11 +## MCP Server Types
12 +
13 +Agent Zero supports three main types of MCP servers:
14 +
15 +1. **Local Stdio Servers**: Local executables that Agent Zero communicates with via standard input/output (stdio).
16 +2. **Remote SSE Servers**: Network-accessible servers that use Server-Sent Events (SSE), usually over HTTP/S.
17 +3. **Remote Streaming HTTP Servers**: Servers using the streamable HTTP transport protocol for MCP communication.
18 +
19 +## How Agent Zero Consumes MCP Tools
20 +
21 +Agent Zero discovers and integrates MCP tools dynamically through the following process:
22 +
23 +1. **Configuration**: MCP servers are defined in the Agent Zero configuration, primarily through the Settings UI.
24 +2. **Saving Settings**: When saved via the UI, Agent Zero updates `usr/settings.json`, specifically the `"mcp_servers"` key.
25 +3. **Server Startup**: Agent Zero initializes configured MCP servers (stdio) or connects to them (remote). For `npx`/`uvx` based servers, the first run downloads packages.
26 +4. **Tool Discovery**: Upon initialization, Agent Zero connects to each enabled MCP server and queries for available tools, descriptions, and parameters.
27 +5. **Dynamic Prompting**: Tool information is injected into the agent's system prompt. The `{{tools}}` placeholder in templates (e.g., `prompts/agent.system.mcp_tools.md`) is replaced with the formatted tool list.
28 +6. **Tool Invocation**: When the LLM requests an MCP tool, Agent Zero's `process_tools` method (`mcp_handler.py`) routes the request to the appropriate MCP server.
29 +
30 +## Configuration File Structure
31 +
32 +### Settings Location
33 +
34 +MCP server configurations are stored in:
35 +- `usr/settings.json` (primary storage)
36 +
37 +### The `mcp_servers` Setting
38 +
39 +Within `usr/settings.json`, MCP servers are defined under the `"mcp_servers"` key:
40 +
41 +- **Value Type**: JSON formatted string containing:
42 + - A JSON object with `"mcpServers"` (recommended, matches UI)
43 + - Or a JSON array of server configurations
44 +- **Default Value**: Empty config (`{"mcpServers": {}}`)
45 +- **Manual Editing**: While UI configuration is recommended, manual editing is possible. Ensure proper JSON string formatting with escaped quotes.
46 +
47 +### Recommended Configuration Format
48 +
49 +```json
50 +{
51 + "mcpServers": {
52 + "sqlite": {
53 + "command": "uvx",
54 + "args": ["mcp-server-sqlite", "--db-path", "/root/db.sqlite"]
55 + },
56 + "deep-wiki": {
57 + "description": "Use this MCP to analyze GitHub repositories",
58 + "url": "https://mcp.deepwiki.com/sse"
59 + }
60 + }
61 +}
62 +```
63 +
64 +> [!NOTE]
65 +> In `usr/settings.json`, the entire `"mcp_servers"` value is stored as a single string. The Settings UI handles escaping automatically.
66 +
67 +### Upgrading Existing Installations
68 +
69 +For existing `settings.json` files without MCP support:
70 +
71 +1. Ensure you're running a version with MCP support
72 +2. Open the settings UI
73 +3. Save settings (even without changes)
74 +4. This writes the complete settings structure including `"mcp_servers": ""`
75 +5. Configure servers via UI or careful manual editing
76 +
77 +## Server Configuration Templates
78 +
79 +### 1. Local Stdio Server
80 +
81 +```json
82 +{
83 + "name": "My Local Tool Server",
84 + "description": "Optional: A brief description of this server.",
85 + "type": "stdio",
86 + "command": "python",
87 + "args": ["path/to/your/mcp_stdio_script.py", "--some-arg"],
88 + "env": {
89 + "PYTHONPATH": "/path/to/custom/libs:.",
90 + "ANOTHER_VAR": "value"
91 + },
92 + "encoding": "utf-8",
93 + "encoding_error_handler": "strict",
94 + "disabled": false
95 +}
96 +```
97 +
98 +**Configuration Fields:**
99 +- `type`: Optional, auto-detected. Can be `"stdio"`, `"sse"`, or streaming variants
100 +- `command`: **Required**. The executable to run
101 +- `args`: Optional list of command arguments
102 +- `env`: Optional environment variables for the process
103 +- `encoding`: Optional, default `"utf-8"`
104 +- `encoding_error_handler`: Optional, can be `"strict"`, `"ignore"`, or `"replace"`
105 +
106 +### 2. Remote SSE Server
107 +
108 +```json
109 +{
110 + "name": "My Remote API Tools",
111 + "description": "Optional: Description of the remote SSE server.",
112 + "type": "sse",
113 + "url": "https://api.example.com/mcp-sse-endpoint",
114 + "headers": {
115 + "Authorization": "Bearer YOUR_API_KEY_OR_TOKEN",
116 + "X-Custom-Header": "some_value"
117 + },
118 + "timeout": 5.0,
119 + "sse_read_timeout": 300.0,
120 + "disabled": false
121 +}
122 +```
123 +
124 +**Configuration Fields:**
125 +- `url`: **Required**. Full URL for the SSE endpoint
126 +- `headers`: Optional HTTP headers for authentication/custom headers
127 +- `timeout`: Optional connection timeout in seconds (default: 5.0)
128 +- `sse_read_timeout`: Optional read timeout for SSE stream (default: 300.0)
129 +
130 +### 3. Remote Streaming HTTP Server
131 +
132 +```json
133 +{
134 + "name": "My Streaming HTTP Tools",
135 + "description": "Optional: Description of the remote streaming HTTP server.",
136 + "type": "streaming-http",
137 + "url": "https://api.example.com/mcp-http-endpoint",
138 + "headers": {
139 + "Authorization": "Bearer YOUR_API_KEY_OR_TOKEN",
140 + "X-Custom-Header": "some_value"
141 + },
142 + "timeout": 5.0,
143 + "sse_read_timeout": 300.0,
144 + "disabled": false
145 +}
146 +```
147 +
148 +**Streaming HTTP Variants:**
149 +Type can be: `"http-stream"`, `"streaming-http"`, `"streamable-http"`, or `"http-streaming"`
150 +
151 +### Example in settings.json
152 +
153 +```json
154 +{
155 + "mcp_servers": "[{'name': 'MyPythonTools', 'command': 'python3', 'args': ['mcp_scripts/my_server.py'], 'disabled': false}, {'name': 'ExternalAPI', 'url': 'https://data.example.com/mcp', 'headers': {'X-Auth-Token': 'supersecret'}, 'disabled': false}]"
156 +}
157 +```
158 +
159 +## Key Configuration Fields
160 +
161 +### Common Fields
162 +
163 +- **`name`**: Unique server identifier. Used to prefix tools (e.g., `server_name.tool_name`). Normalized internally (lowercase, spaces/hyphens → underscores)
164 +- **`type`**: Optional explicit type. Auto-detected if omitted based on `command` (stdio) or `url` (defaults to sse)
165 +- **`disabled`**: Boolean. Set `true` to ignore this server without removing configuration
166 +- **`description`**: Optional human-readable description
167 +
168 +### Type-Specific Required Fields
169 +
170 +- **Stdio servers**: Require `command`
171 +- **Remote servers**: Require `url`
172 +
173 +## Docker Networking Considerations
174 +
175 +### Agent Zero in Docker, MCP Server on Host
176 +
177 +**macOS/Windows:**
178 +```json
179 +{
180 + "url": "http://host.docker.internal:PORT/endpoint"
181 +}
182 +```
183 +
184 +**Linux:**
185 +- Run MCP server in the same Docker network
186 +- Reference by container name: `http://container_name:PORT/endpoint`
187 +
188 +### Remote MCP Servers
189 +
190 +Use standard HTTPS URLs:
191 +```json
192 +{
193 + "url": "https://api.example.com/mcp-endpoint"
194 +}
195 +```
196 +
197 +## Using MCP Tools
198 +
199 +### Tool Naming Convention
200 +
201 +MCP tools are prefixed with the normalized server name:
202 +
203 +- Server name: `"sequential-thinking"`
204 +- Tool name from server: `"run_chain"`
205 +- Final tool name in Agent Zero: `sequential_thinking.run_chain`
206 +
207 +### Agent Interaction
208 +
209 +Instruct the agent to use MCP tools directly:
210 +
211 +```
212 +"Agent, use the sequential_thinking.run_chain tool with the following input..."
213 +```
214 +
215 +The LLM formulates the appropriate JSON request automatically.
216 +
217 +### Execution Flow
218 +
219 +1. `process_tools` method receives tool request
220 +2. `mcp_handler.py` checks if tool name exists in `MCPConfig`
221 +3. If found: delegates to corresponding MCP server
222 +4. If not found: attempts to find built-in tool with that name
223 +
224 +This prioritization allows MCP tools to extend or override built-in functionality.
225 +
226 +## Troubleshooting
227 +
228 +### Server Not Connecting
229 +
230 +**Check status in UI:**
231 +- Settings → MCP/A2A → External MCP Servers
232 +- Green indicator = connected
233 +- Red indicator = connection failed
234 +
235 +**Common issues:**
236 +- Wrong URL or port
237 +- Missing authentication headers
238 +- Network/firewall blocking connection
239 +- Server not running
240 +
241 +### Tools Not Appearing
242 +
243 +**Verification steps:**
244 +1. Confirm server shows as connected (green status)
245 +2. Check server exposes tools (count shown in UI)
246 +3. Verify tool names match server documentation
247 +4. For `npx`/`uvx` servers, first run downloads packages (may take time)
248 +
249 +### Encoding Issues (Stdio Servers)
250 +
251 +Adjust encoding settings:
252 +```json
253 +{
254 + "encoding": "utf-8",
255 + "encoding_error_handler": "replace"
256 +}
257 +```
258 +
259 +Error handler options:
260 +- `"strict"`: Fail on encoding errors (default)
261 +- `"ignore"`: Skip problematic characters
262 +- `"replace"`: Replace with placeholder character
263 +
264 +## Security Considerations
265 +
266 +### API Keys and Secrets
267 +
268 +Store sensitive data securely:
269 +- Use environment variables when possible
270 +- Avoid committing secrets to version control
271 +- Use header-based authentication for remote servers
272 +
273 +### Network Security
274 +
275 +- Use HTTPS for remote MCP servers
276 +- Validate SSL certificates (default behavior)
277 +- Restrict network access to trusted servers only
278 +
279 +### Local Stdio Servers
280 +
281 +- Only run trusted executables
282 +- Review server code before execution
283 +- Use environment isolation when possible
284 +
285 +## Performance Optimization
286 +
287 +### Connection Timeouts
288 +
289 +Adjust for network conditions:
290 +```json
291 +{
292 + "timeout": 10.0, // Initial connection
293 + "sse_read_timeout": 600.0 // Long-running operations
294 +}
295 +```
296 +
297 +### Server Pooling
298 +
299 +For high-frequency tool usage:
300 +- Agent Zero maintains persistent connections to remote servers
301 +- Stdio servers are kept alive between tool calls
302 +- Reduces overhead for repeated operations
303 +
304 +## Advanced Examples
305 +
306 +### Multi-Server Configuration
307 +
308 +```json
309 +{
310 + "mcpServers": {
311 + "browser": {
312 + "command": "npx",
313 + "args": ["-y", "chrome-devtools-mcp@latest"]
314 + },
315 + "database": {
316 + "command": "uvx",
317 + "args": ["mcp-server-sqlite", "--db-path", "/data/app.db"]
318 + },
319 + "external-api": {
320 + "url": "https://api.example.com/mcp",
321 + "headers": {
322 + "Authorization": "Bearer token123"
323 + }
324 + },
325 + "backup-api": {
326 + "url": "https://backup.example.com/mcp",
327 + "disabled": true
328 + }
329 + }
330 +}
331 +```
332 +
333 +### Custom Environment Variables
334 +
335 +```json
336 +{
337 + "mcpServers": {
338 + "python-tools": {
339 + "command": "python3",
340 + "args": ["/opt/tools/mcp_server.py"],
341 + "env": {
342 + "PYTHONPATH": "/opt/libs:/usr/local/lib/python3.9",
343 + "API_KEY": "secret_key",
344 + "DEBUG": "true"
345 + }
346 + }
347 + }
348 +}
349 +```
350 +
351 +## Integration Patterns
352 +
353 +### Tool Composition
354 +
355 +Combine multiple MCP servers for complex workflows:
356 +1. Browser MCP for data extraction
357 +2. Database MCP for storage
358 +3. Workflow MCP for orchestration
359 +
360 +Agent Zero can chain these tools automatically based on task requirements.
361 +
362 +### Fallback Configuration
363 +
364 +```json
365 +{
366 + "mcpServers": {
367 + "primary-service": {
368 + "url": "https://primary.example.com/mcp"
369 + },
370 + "fallback-service": {
371 + "url": "https://fallback.example.com/mcp",
372 + "disabled": true
373 + }
374 + }
375 +}
376 +```
377 +
378 +Enable fallback manually when primary service is unavailable.
379 +
380 +## Development and Testing
381 +
382 +### Testing MCP Configurations
383 +
384 +1. Add server with `disabled: false`
385 +2. Save and check connection status
386 +3. Test individual tools via agent prompts
387 +4. Monitor logs for errors
388 +5. Adjust configuration as needed
389 +
390 +### Creating Custom MCP Servers
391 +
392 +For developing custom MCP servers:
393 +- Follow MCP protocol specifications
394 +- Implement stdio or HTTP transport
395 +- Provide clear tool descriptions
396 +- Test with Agent Zero before production
397 +
398 +See [MCP Protocol Documentation](https://modelcontextprotocol.io) for implementation details.
399 +
400 +## Related Documentation
401 +
402 +- [MCP Setup](../guides/mcp-setup.md) - Quick start guide
403 +- [Connectivity: MCP Server](connectivity.md#mcp-server-connectivity) - Exposing Agent Zero as MCP server
404 +- [Advanced: Extensions](extensions.md) - Custom tools and extensions
docs/developer/notifications.md renamed
docs/developer/websockets.md renamed
-4
@@ -1,9 +1,5 @@
1 # WebSocket Infrastructure Guide
2
3 -**Audience**: Backend and frontend developers building real-time features on Agent Zero
4 -**Updated**: 2026-01-02
5 -**Related Specs**: `specs/003-websocket-event-handlers/*`
6 -
3 This guide consolidates everything you need to design, implement, and troubleshoot Agent Zero WebSocket flows. It complements the feature specification by describing day-to-day developer tasks, showing how backend handlers and frontend clients cooperate, and documenting practical patterns for producers and consumers on both sides of the connection.
4
5 ---
docs/development/designs/backup-specification-backend.md deleted
-1708
@@ -1,1708 +0,0 @@
1 -# Agent Zero Backup/Restore Backend Specification
2 -
3 -## Overview
4 -This specification defines the backend implementation for Agent Zero's backup and restore functionality, providing users with the ability to backup and restore their Agent Zero configurations, data, and custom files using glob pattern-based selection. The backup functionality is implemented as a dedicated "backup" tab in the settings interface for easy access and organization.
5 -
6 -## Core Requirements
7 -
8 -### Backup Flow
9 -1. User configures backup paths using glob patterns in settings modal
10 -2. Backend creates zip archive with selected files and metadata
11 -3. Archive is provided as download to user
12 -
13 -### Restore Flow
14 -1. User uploads backup archive in settings modal
15 -2. Backend extracts and validates metadata
16 -3. User confirms file list and destination paths
17 -4. Backend restores files to specified locations
18 -
19 -## Backend Architecture
20 -
21 -### 1. Settings Integration
22 -
23 -#### Settings Schema Extension
24 -Add backup/restore section with dedicated tab to `python/helpers/settings.py`:
25 -
26 -**Integration Notes:**
27 -- Leverages existing settings button handler pattern (follows MCP servers example)
28 -- Integrates with Agent Zero's established error handling and toast notification system
29 -- Uses existing file operation helpers with RFC support for development mode compatibility
30 -
31 -```python
32 -# Add to SettingsSection in convert_out() function
33 -backup_section: SettingsSection = {
34 - "id": "backup_restore",
35 - "title": "Backup & Restore",
36 - "description": "Backup and restore Agent Zero data and configurations using glob pattern-based file selection.",
37 - "fields": [
38 - {
39 - "id": "backup_create",
40 - "title": "Create Backup",
41 - "description": "Create a backup archive of selected files and configurations using customizable patterns.",
42 - "type": "button",
43 - "value": "Create Backup",
44 - },
45 - {
46 - "id": "backup_restore",
47 - "title": "Restore from Backup",
48 - "description": "Restore files and configurations from a backup archive with pattern-based selection.",
49 - "type": "button",
50 - "value": "Restore Backup",
51 - }
52 - ],
53 - "tab": "backup", # Dedicated backup tab for clean organization
54 -}
55 -```
56 -
57 -#### Default Backup Configuration
58 -The backup system now uses **resolved absolute filesystem paths** instead of placeholders, ensuring compatibility across different deployment environments (Docker containers, direct host installations, different users).
59 -
60 -```python
61 -def _get_default_patterns(self) -> str:
62 - """Get default backup patterns with resolved absolute paths"""
63 - # Ensure paths don't have double slashes
64 - agent_root = self.agent_zero_root.rstrip('/')
65 - user_home = self.user_home.rstrip('/')
66 -
67 - return f"""# Agent Zero Knowledge (excluding defaults)
68 -{agent_root}/knowledge/**
69 -!{agent_root}/knowledge/default/**
70 -
71 -# Agent Zero Instruments (excluding defaults)
72 -{agent_root}/instruments/**
73 -!{agent_root}/instruments/default/**
74 -
75 -# Memory (excluding embeddings cache)
76 -{agent_root}/memory/**
77 -!{agent_root}/memory/embeddings/**
78 -
79 -# Configuration and Settings (CRITICAL)
80 -{agent_root}/.env
81 -{agent_root}/tmp/settings.json
82 -{agent_root}/tmp/chats/**
83 -{agent_root}/tmp/tasks/**
84 -{agent_root}/tmp/uploads/**
85 -
86 -# User Home Directory (excluding hidden files by default)
87 -{user_home}/**
88 -!{user_home}/.*/**
89 -!{user_home}/.*"""
90 -```
91 -
92 -**Example Resolved Patterns** (varies by environment):
93 -```
94 -# Docker container environment
95 -/a0/knowledge/**
96 -!/a0/knowledge/default/**
97 -/root/**
98 -!/root/.*/**
99 -!/root/.*
100 -
101 -# Host environment
102 -/home/rafael/a0/data/knowledge/**
103 -!/home/rafael/a0/data/knowledge/default/**
104 -/home/rafael/**
105 -!/home/rafael/.*/**
106 -!/home/rafael/.*
107 -```
108 -
109 -> **⚠️ CRITICAL FILE NOTICE**: The `{agent_root}/.env` file contains essential configuration including API keys, model settings, and runtime parameters. This file is **REQUIRED** for Agent Zero to function properly and should always be included in backups alongside `settings.json`. Without this file, restored Agent Zero instances will not have access to configured language models or external services.
110 -
111 -### 2. API Endpoints
112 -
113 -#### 2.1 Backup Test Endpoint
114 -**File**: `python/api/backup_test.py`
115 -
116 -```python
117 -from python.helpers.api import ApiHandler
118 -from flask import Request, Response
119 -from python.helpers.backup import BackupService
120 -import json
121 -
122 -class BackupTest(ApiHandler):
123 - """Test backup patterns and return matched files"""
124 -
125 - @classmethod
126 - def requires_auth(cls) -> bool:
127 - return True
128 -
129 - @classmethod
130 - def requires_loopback(cls) -> bool:
131 - return True
132 -
133 - async def process(self, input: dict, request: Request) -> dict | Response:
134 - patterns = input.get("patterns", "")
135 - include_hidden = input.get("include_hidden", False)
136 - max_files = input.get("max_files", 1000) # Limit for preview
137 -
138 - try:
139 - backup_service = BackupService()
140 - matched_files = await backup_service.test_patterns(
141 - patterns=patterns,
142 - include_hidden=include_hidden,
143 - max_files=max_files
144 - )
145 -
146 - return {
147 - "success": True,
148 - "files": matched_files,
149 - "total_count": len(matched_files),
150 - "truncated": len(matched_files) >= max_files
151 - }
152 -
153 - except Exception as e:
154 - return {
155 - "success": False,
156 - "error": str(e)
157 - }
158 -```
159 -
160 -#### 2.2 Backup Create Endpoint
161 -**File**: `python/api/backup_create.py`
162 -
163 -```python
164 -from python.helpers.api import ApiHandler
165 -from flask import Request, Response, send_file
166 -from python.helpers.backup import BackupService
167 -import tempfile
168 -import os
169 -
170 -class BackupCreate(ApiHandler):
171 - """Create backup archive and provide download"""
172 -
173 - @classmethod
174 - def requires_auth(cls) -> bool:
175 - return True
176 -
177 - @classmethod
178 - def requires_loopback(cls) -> bool:
179 - return True
180 -
181 - async def process(self, input: dict, request: Request) -> dict | Response:
182 - patterns = input.get("patterns", "")
183 - include_hidden = input.get("include_hidden", False)
184 - backup_name = input.get("backup_name", "agent-zero-backup")
185 -
186 - try:
187 - backup_service = BackupService()
188 - zip_path = await backup_service.create_backup(
189 - patterns=patterns,
190 - include_hidden=include_hidden,
191 - backup_name=backup_name
192 - )
193 -
194 - # Return file for download
195 - return send_file(
196 - zip_path,
197 - as_attachment=True,
198 - download_name=f"{backup_name}.zip",
199 - mimetype='application/zip'
200 - )
201 -
202 - except Exception as e:
203 - return {
204 - "success": False,
205 - "error": str(e)
206 - }
207 -```
208 -
209 -#### 2.3 Backup Restore Endpoint
210 -**File**: `python/api/backup_restore.py`
211 -
212 -```python
213 -from python.helpers.api import ApiHandler
214 -from flask import Request, Response
215 -from python.helpers.backup import BackupService
216 -from werkzeug.datastructures import FileStorage
217 -
218 -class BackupRestore(ApiHandler):
219 - """Restore files from backup archive"""
220 -
221 - @classmethod
222 - def requires_auth(cls) -> bool:
223 - return True
224 -
225 - @classmethod
226 - def requires_loopback(cls) -> bool:
227 - return True
228 -
229 - async def process(self, input: dict, request: Request) -> dict | Response:
230 - # Handle file upload
231 - if 'backup_file' not in request.files:
232 - return {"success": False, "error": "No backup file provided"}
233 -
234 - backup_file: FileStorage = request.files['backup_file']
235 - if backup_file.filename == '':
236 - return {"success": False, "error": "No file selected"}
237 -
238 - # Get restore configuration
239 - restore_patterns = input.get("restore_patterns", "")
240 - overwrite_policy = input.get("overwrite_policy", "overwrite") # overwrite, skip, backup
241 -
242 - try:
243 - backup_service = BackupService()
244 - result = await backup_service.restore_backup(
245 - backup_file=backup_file,
246 - restore_patterns=restore_patterns,
247 - overwrite_policy=overwrite_policy
248 - )
249 -
250 - return {
251 - "success": True,
252 - "restored_files": result["restored_files"],
253 - "skipped_files": result["skipped_files"],
254 - "errors": result["errors"]
255 - }
256 -
257 - except Exception as e:
258 - return {
259 - "success": False,
260 - "error": str(e)
261 - }
262 -```
263 -
264 -#### 2.4 Backup Restore Preview Endpoint
265 -**File**: `python/api/backup_restore_preview.py`
266 -
267 -```python
268 -from python.helpers.api import ApiHandler
269 -from flask import Request, Response
270 -from python.helpers.backup import BackupService
271 -from werkzeug.datastructures import FileStorage
272 -
273 -class BackupRestorePreview(ApiHandler):
274 - """Preview files that would be restored based on patterns"""
275 -
276 - @classmethod
277 - def requires_auth(cls) -> bool:
278 - return True
279 -
280 - @classmethod
281 - def requires_loopback(cls) -> bool:
282 - return True
283 -
284 - async def process(self, input: dict, request: Request) -> dict | Response:
285 - # Handle file upload
286 - if 'backup_file' not in request.files:
287 - return {"success": False, "error": "No backup file provided"}
288 -
289 - backup_file: FileStorage = request.files['backup_file']
290 - if backup_file.filename == '':
291 - return {"success": False, "error": "No file selected"}
292 -
293 - restore_patterns = input.get("restore_patterns", "")
294 -
295 - try:
296 - backup_service = BackupService()
297 - preview_result = await backup_service.preview_restore(
298 - backup_file=backup_file,
299 - restore_patterns=restore_patterns
300 - )
301 -
302 - return {
303 - "success": True,
304 - "files": preview_result["files"],
305 - "total_count": preview_result["total_count"],
306 - "skipped_count": preview_result["skipped_count"]
307 - }
308 -
309 - except Exception as e:
310 - return {
311 - "success": False,
312 - "error": str(e)
313 - }
314 -```
315 -
316 -#### 2.5 Backup File Preview Grouped Endpoint
317 -**File**: `python/api/backup_preview_grouped.py`
318 -
319 -```python
320 -from python.helpers.api import ApiHandler
321 -from flask import Request, Response
322 -from python.helpers.backup import BackupService
323 -
324 -class BackupPreviewGrouped(ApiHandler):
325 - """Get grouped file preview with smart directory organization"""
326 -
327 - @classmethod
328 - def requires_auth(cls) -> bool:
329 - return True
330 -
331 - @classmethod
332 - def requires_loopback(cls) -> bool:
333 - return True
334 -
335 - async def process(self, input: dict, request: Request) -> dict | Response:
336 - patterns = input.get("patterns", "")
337 - include_hidden = input.get("include_hidden", False)
338 - max_depth = input.get("max_depth", 3)
339 - search_filter = input.get("search_filter", "")
340 -
341 - try:
342 - backup_service = BackupService()
343 - grouped_preview = await backup_service.get_grouped_file_preview(
344 - patterns=patterns,
345 - include_hidden=include_hidden,
346 - max_depth=max_depth,
347 - search_filter=search_filter
348 - )
349 -
350 - return {
351 - "success": True,
352 - "groups": grouped_preview["groups"],
353 - "stats": grouped_preview["stats"],
354 - "total_files": grouped_preview["total_files"],
355 - "total_size": grouped_preview["total_size"]
356 - }
357 -
358 - except Exception as e:
359 - return {
360 - "success": False,
361 - "error": str(e)
362 - }
363 -```
364 -
365 -#### 2.6 Backup Progress Stream Endpoint
366 -**File**: `python/api/backup_progress_stream.py`
367 -
368 -```python
369 -from python.helpers.api import ApiHandler
370 -from flask import Request, Response, stream_template
371 -from python.helpers.backup import BackupService
372 -import json
373 -
374 -class BackupProgressStream(ApiHandler):
375 - """Stream real-time backup progress"""
376 -
377 - @classmethod
378 - def requires_auth(cls) -> bool:
379 - return True
380 -
381 - @classmethod
382 - def requires_loopback(cls) -> bool:
383 - return True
384 -
385 - async def process(self, input: dict, request: Request) -> dict | Response:
386 - patterns = input.get("patterns", "")
387 - include_hidden = input.get("include_hidden", False)
388 - backup_name = input.get("backup_name", "agent-zero-backup")
389 -
390 - def generate_progress():
391 - try:
392 - backup_service = BackupService()
393 -
394 - # Generator function for streaming progress
395 - for progress_data in backup_service.create_backup_with_progress(
396 - patterns=patterns,
397 - include_hidden=include_hidden,
398 - backup_name=backup_name
399 - ):
400 - yield f"data: {json.dumps(progress_data)}\n\n"
401 -
402 - except Exception as e:
403 - yield f"data: {json.dumps({'error': str(e), 'completed': True})}\n\n"
404 -
405 - return Response(
406 - generate_progress(),
407 - content_type='text/event-stream',
408 - headers={
409 - 'Cache-Control': 'no-cache',
410 - 'Connection': 'keep-alive'
411 - }
412 - )
413 -```
414 -
415 -#### 2.7 Backup Inspect Endpoint
416 -**File**: `python/api/backup_inspect.py`
417 -
418 -```python
419 -from python.helpers.api import ApiHandler
420 -from flask import Request, Response
421 -from python.helpers.backup import BackupService
422 -from werkzeug.datastructures import FileStorage
423 -
424 -class BackupInspect(ApiHandler):
425 - """Inspect backup archive and return metadata"""
426 -
427 - @classmethod
428 - def requires_auth(cls) -> bool:
429 - return True
430 -
431 - @classmethod
432 - def requires_loopback(cls) -> bool:
433 - return True
434 -
435 - async def process(self, input: dict, request: Request) -> dict | Response:
436 - # Handle file upload
437 - if 'backup_file' not in request.files:
438 - return {"success": False, "error": "No backup file provided"}
439 -
440 - backup_file: FileStorage = request.files['backup_file']
441 - if backup_file.filename == '':
442 - return {"success": False, "error": "No file selected"}
443 -
444 - try:
445 - backup_service = BackupService()
446 - metadata = await backup_service.inspect_backup(backup_file)
447 -
448 - return {
449 - "success": True,
450 - "metadata": metadata,
451 - "files": metadata.get("files", []),
452 - "include_patterns": metadata.get("include_patterns", []), # Array of include patterns
453 - "exclude_patterns": metadata.get("exclude_patterns", []), # Array of exclude patterns
454 - "default_patterns": metadata.get("backup_config", {}).get("default_patterns", ""),
455 - "agent_zero_version": metadata.get("agent_zero_version", "unknown"),
456 - "timestamp": metadata.get("timestamp", ""),
457 - "backup_name": metadata.get("backup_name", ""),
458 - "total_files": metadata.get("total_files", len(metadata.get("files", []))),
459 - "backup_size": metadata.get("backup_size", 0),
460 - "include_hidden": metadata.get("include_hidden", False)
461 - }
462 -
463 - except Exception as e:
464 - return {
465 - "success": False,
466 - "error": str(e)
467 - }
468 -```
469 -
470 -### 3. Backup Service Implementation
471 -
472 -#### Core Service Class
473 -**File**: `python/helpers/backup.py`
474 -
475 -**RFC Integration Notes:**
476 -The BackupService leverages Agent Zero's existing file operation helpers which already support RFC (Remote Function Call) routing for development mode. This ensures seamless operation whether running in direct mode or with container isolation.
477 -
478 -```python
479 -import zipfile
480 -import json
481 -import os
482 -import tempfile
483 -import datetime
484 -from typing import List, Dict, Any, Optional
485 -from pathspec import PathSpec
486 -from pathspec.patterns import GitWildMatchPattern
487 -from python.helpers import files, runtime, git
488 -import shutil
489 -
490 -class BackupService:
491 - """Core backup and restore service for Agent Zero"""
492 -
493 - def __init__(self):
494 - self.agent_zero_version = self._get_agent_zero_version()
495 - self.agent_zero_root = files.get_abs_path("") # Resolved Agent Zero root
496 - self.user_home = os.path.expanduser("~") # Current user's home directory
497 -
498 - def _get_default_patterns(self) -> str:
499 - """Get default backup patterns from specification"""
500 - return DEFAULT_BACKUP_PATTERNS
501 -
502 - def _get_agent_zero_version(self) -> str:
503 - """Get current Agent Zero version"""
504 - try:
505 - # Get version from git info (same as run_ui.py)
506 - gitinfo = git.get_git_info()
507 - return gitinfo.get("version", "development")
508 - except:
509 - return "unknown"
510 -
511 - def _resolve_path(self, pattern_path: str) -> str:
512 - """Resolve pattern path to absolute system path (now patterns are already absolute)"""
513 - return pattern_path
514 -
515 - def _unresolve_path(self, abs_path: str) -> str:
516 - """Convert absolute path back to pattern path (now patterns are already absolute)"""
517 - return abs_path
518 -
519 - def _parse_patterns(self, patterns: str) -> tuple[list[str], list[str]]:
520 - """Parse patterns string into include and exclude pattern arrays"""
521 - include_patterns = []
522 - exclude_patterns = []
523 -
524 - for line in patterns.split('\n'):
525 - line = line.strip()
526 - if not line or line.startswith('#'):
527 - continue
528 -
529 - if line.startswith('!'):
530 - # Exclude pattern
531 - exclude_patterns.append(line[1:]) # Remove the '!' prefix
532 - else:
533 - # Include pattern
534 - include_patterns.append(line)
535 -
536 - return include_patterns, exclude_patterns
537 -
538 - def _patterns_to_string(self, include_patterns: list[str], exclude_patterns: list[str]) -> str:
539 - """Convert pattern arrays back to patterns string for pathspec processing"""
540 - patterns = []
541 -
542 - # Add include patterns
543 - for pattern in include_patterns:
544 - patterns.append(pattern)
545 -
546 - # Add exclude patterns with '!' prefix
547 - for pattern in exclude_patterns:
548 - patterns.append(f"!{pattern}")
549 -
550 - return '\n'.join(patterns)
551 -
552 - async def _get_system_info(self) -> Dict[str, Any]:
553 - """Collect system information for metadata"""
554 - import platform
555 - import psutil
556 -
557 - try:
558 - return {
559 - "platform": platform.platform(),
560 - "system": platform.system(),
561 - "release": platform.release(),
562 - "version": platform.version(),
563 - "machine": platform.machine(),
564 - "processor": platform.processor(),
565 - "architecture": platform.architecture()[0],
566 - "hostname": platform.node(),
567 - "python_version": platform.python_version(),
568 - "cpu_count": str(psutil.cpu_count()),
569 - "memory_total": str(psutil.virtual_memory().total),
570 - "disk_usage": str(psutil.disk_usage('/').total if os.path.exists('/') else 0)
571 - }
572 - except Exception as e:
573 - return {"error": f"Failed to collect system info: {str(e)}"}
574 -
575 - async def _get_environment_info(self) -> Dict[str, Any]:
576 - """Collect environment information for metadata"""
577 - try:
578 - return {
579 - "user": os.environ.get("USER", "unknown"),
580 - "home": os.environ.get("HOME", "unknown"),
581 - "shell": os.environ.get("SHELL", "unknown"),
582 - "path": os.environ.get("PATH", "")[:200] + "..." if len(os.environ.get("PATH", "")) > 200 else os.environ.get("PATH", ""),
583 - "timezone": str(datetime.datetime.now().astimezone().tzinfo),
584 - "working_directory": os.getcwd(),
585 - "agent_zero_root": files.get_abs_path(""),
586 - "runtime_mode": "development" if runtime.is_development() else "production"
587 - }
588 - except Exception as e:
589 - return {"error": f"Failed to collect environment info: {str(e)}"}
590 -
591 - async def _get_backup_author(self) -> str:
592 - """Get backup author/system identifier"""
593 - try:
594 - import getpass
595 - username = getpass.getuser()
596 - hostname = platform.node()
597 - return f"{username}@{hostname}"
598 - except:
599 - return "unknown"
600 -
601 - async def _calculate_file_checksums(self, matched_files: List[Dict[str, Any]]) -> Dict[str, str]:
602 - """Calculate SHA-256 checksums for files"""
603 - import hashlib
604 -
605 - checksums = {}
606 - for file_info in matched_files:
607 - try:
608 - real_path = file_info["real_path"]
609 - if os.path.exists(real_path) and os.path.isfile(real_path):
610 - hash_sha256 = hashlib.sha256()
611 - with open(real_path, "rb") as f:
612 - for chunk in iter(lambda: f.read(4096), b""):
613 - hash_sha256.update(chunk)
614 - checksums[real_path] = hash_sha256.hexdigest()
615 - except Exception:
616 - checksums[file_info["real_path"]] = "error"
617 -
618 - return checksums
619 -
620 - async def _count_directories(self, matched_files: List[Dict[str, Any]]) -> int:
621 - """Count unique directories in file list"""
622 - directories = set()
623 - for file_info in matched_files:
624 - dir_path = os.path.dirname(file_info["path"])
625 - if dir_path:
626 - directories.add(dir_path)
627 - return len(directories)
628 -
629 - def _calculate_backup_checksum(self, zip_path: str) -> str:
630 - """Calculate checksum of the entire backup file"""
631 - import hashlib
632 -
633 - try:
634 - hash_sha256 = hashlib.sha256()
635 - with open(zip_path, "rb") as f:
636 - for chunk in iter(lambda: f.read(4096), b""):
637 - hash_sha256.update(chunk)
638 - return hash_sha256.hexdigest()
639 - except Exception:
640 - return "error"
641 -
642 - async def test_patterns(self, patterns: str, include_hidden: bool = False, max_files: int = 1000) -> List[Dict[str, Any]]:
643 - """Test backup patterns and return list of matched files"""
644 -
645 - # Parse patterns using pathspec
646 - pattern_lines = [line.strip() for line in patterns.split('\n') if line.strip() and not line.strip().startswith('#')]
647 -
648 - if not pattern_lines:
649 - return []
650 -
651 - matched_files = []
652 - processed_count = 0
653 -
654 - try:
655 - spec = PathSpec.from_lines(GitWildMatchPattern, pattern_lines)
656 -
657 - # Walk through base directories
658 - for base_pattern_path, base_real_path in self.base_paths.items():
659 - if not os.path.exists(base_real_path):
660 - continue
661 -
662 - for root, dirs, files_list in os.walk(base_real_path):
663 - # Filter hidden directories if not included
664 - if not include_hidden:
665 - dirs[:] = [d for d in dirs if not d.startswith('.')]
666 -
667 - for file in files_list:
668 - if processed_count >= max_files:
669 - break
670 -
671 - # Skip hidden files if not included
672 - if not include_hidden and file.startswith('.'):
673 - continue
674 -
675 - file_path = os.path.join(root, file)
676 - pattern_path = self._unresolve_path(file_path)
677 -
678 - # Remove leading slash for pathspec matching
679 - relative_path = pattern_path.lstrip('/')
680 -
681 - if spec.match_file(relative_path):
682 - try:
683 - stat = os.stat(file_path)
684 - matched_files.append({
685 - "path": pattern_path,
686 - "real_path": file_path,
687 - "size": stat.st_size,
688 - "modified": datetime.datetime.fromtimestamp(stat.st_mtime).isoformat(),
689 - "type": "file"
690 - })
691 - processed_count += 1
692 - except (OSError, IOError):
693 - # Skip files we can't access
694 - continue
695 -
696 - if processed_count >= max_files:
697 - break
698 -
699 - if processed_count >= max_files:
700 - break
701 -
702 - except Exception as e:
703 - raise Exception(f"Error processing patterns: {str(e)}")
704 -
705 - return matched_files
706 -
707 - async def create_backup(self, patterns: str, include_hidden: bool = False, backup_name: str = "agent-zero-backup") -> str:
708 - """Create backup archive with selected files"""
709 -
710 - # Get matched files
711 - matched_files = await self.test_patterns(patterns, include_hidden, max_files=10000)
712 -
713 - if not matched_files:
714 - raise Exception("No files matched the backup patterns")
715 -
716 - # Create temporary zip file
717 - temp_dir = tempfile.mkdtemp()
718 - zip_path = os.path.join(temp_dir, f"{backup_name}.zip")
719 -
720 - try:
721 - with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
722 - # Calculate file checksums for integrity verification
723 - file_checksums = await self._calculate_file_checksums(matched_files)
724 -
725 - # Add comprehensive metadata - this is the control file for backup/restore
726 - include_patterns, exclude_patterns = self._parse_patterns(patterns)
727 -
728 - metadata = {
729 - # Basic backup information
730 - "agent_zero_version": self.agent_zero_version,
731 - "timestamp": datetime.datetime.now().isoformat(),
732 - "backup_name": backup_name,
733 - "include_hidden": include_hidden,
734 -
735 - # Pattern arrays for granular control during restore
736 - "include_patterns": include_patterns, # Array of include patterns
737 - "exclude_patterns": exclude_patterns, # Array of exclude patterns
738 -
739 - # System and environment information
740 - "system_info": await self._get_system_info(),
741 - "environment_info": await self._get_environment_info(),
742 - "backup_author": await self._get_backup_author(),
743 -
744 - # Backup configuration
745 - "backup_config": {
746 - "default_patterns": self._get_default_patterns(),
747 - "include_hidden": include_hidden,
748 - "compression_level": 6,
749 - "integrity_check": True
750 - },
751 -
752 - # File information with checksums
753 - "files": [
754 - {
755 - "path": f["path"],
756 - "size": f["size"],
757 - "modified": f["modified"],
758 - "checksum": file_checksums.get(f["real_path"], ""),
759 - "type": "file"
760 - }
761 - for f in matched_files
762 - ],
763 -
764 - # Statistics
765 - "total_files": len(matched_files),
766 - "backup_size": sum(f["size"] for f in matched_files),
767 - "directory_count": await self._count_directories(matched_files),
768 -
769 - # Integrity verification
770 - "backup_checksum": "", # Will be calculated after backup creation
771 - "verification_method": "sha256"
772 - }
773 -
774 - zipf.writestr("metadata.json", json.dumps(metadata, indent=2))
775 -
776 - # Add files
777 - for file_info in matched_files:
778 - real_path = file_info["real_path"]
779 - archive_path = file_info["path"].lstrip('/')
780 -
781 - try:
782 - if os.path.exists(real_path) and os.path.isfile(real_path):
783 - zipf.write(real_path, archive_path)
784 - except (OSError, IOError) as e:
785 - # Log error but continue with other files
786 - print(f"Warning: Could not backup file {real_path}: {e}")
787 - continue
788 -
789 - return zip_path
790 -
791 - except Exception as e:
792 - # Cleanup on error
793 - if os.path.exists(zip_path):
794 - os.remove(zip_path)
795 - raise Exception(f"Error creating backup: {str(e)}")
796 -
797 - async def inspect_backup(self, backup_file) -> Dict[str, Any]:
798 - """Inspect backup archive and return metadata"""
799 -
800 - # Save uploaded file temporarily
801 - temp_dir = tempfile.mkdtemp()
802 - temp_file = os.path.join(temp_dir, "backup.zip")
803 -
804 - try:
805 - backup_file.save(temp_file)
806 -
807 - with zipfile.ZipFile(temp_file, 'r') as zipf:
808 - # Read metadata
809 - if "metadata.json" not in zipf.namelist():
810 - raise Exception("Invalid backup file: missing metadata.json")
811 -
812 - metadata_content = zipf.read("metadata.json").decode('utf-8')
813 - metadata = json.loads(metadata_content)
814 -
815 - # Add file list from archive
816 - files_in_archive = [name for name in zipf.namelist() if name != "metadata.json"]
817 - metadata["files_in_archive"] = files_in_archive
818 -
819 - return metadata
820 -
821 - except zipfile.BadZipFile:
822 - raise Exception("Invalid backup file: not a valid zip archive")
823 - except json.JSONDecodeError:
824 - raise Exception("Invalid backup file: corrupted metadata")
825 - finally:
826 - # Cleanup
827 - if os.path.exists(temp_file):
828 - os.remove(temp_file)
829 - if os.path.exists(temp_dir):
830 - os.rmdir(temp_dir)
831 -
832 - async def get_grouped_file_preview(self, patterns: str, include_hidden: bool = False, max_depth: int = 3, search_filter: str = "") -> Dict[str, Any]:
833 - """Get files organized in smart groups with depth limitation"""
834 -
835 - # Get all matched files
836 - all_files = await self.test_patterns(patterns, include_hidden, max_files=10000)
837 -
838 - # Apply search filter if provided
839 - if search_filter.strip():
840 - search_lower = search_filter.lower()
841 - all_files = [f for f in all_files if search_lower in f["path"].lower()]
842 -
843 - # Group files by directory structure
844 - groups = {}
845 - total_size = 0
846 -
847 - for file_info in all_files:
848 - path = file_info["path"]
849 - total_size += file_info["size"]
850 -
851 - # Split path and limit depth
852 - path_parts = path.strip('/').split('/')
853 -
854 - # Limit to max_depth for grouping
855 - if len(path_parts) > max_depth:
856 - group_path = '/' + '/'.join(path_parts[:max_depth])
857 - is_truncated = True
858 - else:
859 - group_path = '/' + '/'.join(path_parts[:-1]) if len(path_parts) > 1 else '/'
860 - is_truncated = False
861 -
862 - if group_path not in groups:
863 - groups[group_path] = {
864 - "path": group_path,
865 - "files": [],
866 - "file_count": 0,
867 - "total_size": 0,
868 - "is_truncated": False,
869 - "subdirectories": set()
870 - }
871 -
872 - groups[group_path]["files"].append(file_info)
873 - groups[group_path]["file_count"] += 1
874 - groups[group_path]["total_size"] += file_info["size"]
875 - groups[group_path]["is_truncated"] = groups[group_path]["is_truncated"] or is_truncated
876 -
877 - # Track subdirectories for truncated groups
878 - if is_truncated and len(path_parts) > max_depth:
879 - next_dir = path_parts[max_depth]
880 - groups[group_path]["subdirectories"].add(next_dir)
881 -
882 - # Convert groups to sorted list and add display info
883 - sorted_groups = []
884 - for group_path, group_info in sorted(groups.items()):
885 - group_info["subdirectories"] = sorted(list(group_info["subdirectories"]))
886 -
887 - # Limit displayed files for UI performance
888 - if len(group_info["files"]) > 50:
889 - group_info["displayed_files"] = group_info["files"][:50]
890 - group_info["additional_files"] = len(group_info["files"]) - 50
891 - else:
892 - group_info["displayed_files"] = group_info["files"]
893 - group_info["additional_files"] = 0
894 -
895 - sorted_groups.append(group_info)
896 -
897 - return {
898 - "groups": sorted_groups,
899 - "stats": {
900 - "total_groups": len(sorted_groups),
901 - "total_files": len(all_files),
902 - "total_size": total_size,
903 - "search_applied": bool(search_filter.strip()),
904 - "max_depth": max_depth
905 - },
906 - "total_files": len(all_files),
907 - "total_size": total_size
908 - }
909 -
910 - def create_backup_with_progress(self, patterns: str, include_hidden: bool = False, backup_name: str = "agent-zero-backup"):
911 - """Generator that yields backup progress for streaming"""
912 -
913 - try:
914 - # Step 1: Get matched files
915 - yield {
916 - "stage": "discovery",
917 - "message": "Scanning files...",
918 - "progress": 0,
919 - "completed": False
920 - }
921 -
922 - import asyncio
923 - matched_files = asyncio.run(self.test_patterns(patterns, include_hidden, max_files=10000))
924 -
925 - if not matched_files:
926 - yield {
927 - "stage": "error",
928 - "message": "No files matched the backup patterns",
929 - "progress": 0,
930 - "completed": True,
931 - "error": True
932 - }
933 - return
934 -
935 - total_files = len(matched_files)
936 -
937 - yield {
938 - "stage": "discovery",
939 - "message": f"Found {total_files} files to backup",
940 - "progress": 10,
941 - "completed": False,
942 - "total_files": total_files
943 - }
944 -
945 - # Step 2: Calculate checksums
946 - yield {
947 - "stage": "checksums",
948 - "message": "Calculating file checksums...",
949 - "progress": 15,
950 - "completed": False
951 - }
952 -
953 - file_checksums = asyncio.run(self._calculate_file_checksums(matched_files))
954 -
955 - # Step 3: Create backup
956 - temp_dir = tempfile.mkdtemp()
957 - zip_path = os.path.join(temp_dir, f"{backup_name}.zip")
958 -
959 - yield {
960 - "stage": "backup",
961 - "message": "Creating backup archive...",
962 - "progress": 20,
963 - "completed": False
964 - }
965 -
966 - with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
967 - # Create and add metadata first
968 - metadata = {
969 - "agent_zero_version": self.agent_zero_version,
970 - "timestamp": datetime.datetime.now().isoformat(),
971 - "backup_name": backup_name,
972 - "backup_patterns": patterns,
973 - "include_hidden": include_hidden,
974 - "system_info": asyncio.run(self._get_system_info()),
975 - "environment_info": asyncio.run(self._get_environment_info()),
976 - "backup_author": asyncio.run(self._get_backup_author()),
977 - "backup_config": {
978 - "default_patterns": self._get_default_patterns(),
979 - "custom_patterns": patterns,
980 - "include_hidden": include_hidden,
981 - "compression_level": 6,
982 - "integrity_check": True
983 - },
984 - "files": [
985 - {
986 - "path": f["path"],
987 - "size": f["size"],
988 - "modified": f["modified"],
989 - "checksum": file_checksums.get(f["real_path"], ""),
990 - "type": "file"
991 - }
992 - for f in matched_files
993 - ],
994 - "total_files": len(matched_files),
995 - "backup_size": sum(f["size"] for f in matched_files),
996 - "directory_count": asyncio.run(self._count_directories(matched_files)),
997 - "backup_checksum": "",
998 - "verification_method": "sha256"
999 - }
1000 -
1001 - zipf.writestr("metadata.json", json.dumps(metadata, indent=2))
1002 -
1003 - # Add files with progress updates
1004 - for i, file_info in enumerate(matched_files):
1005 - real_path = file_info["real_path"]
1006 - archive_path = file_info["path"].lstrip('/')
1007 -
1008 - try:
1009 - if os.path.exists(real_path) and os.path.isfile(real_path):
1010 - zipf.write(real_path, archive_path)
1011 -
1012 - # Yield progress every 10 files or at key milestones
1013 - if i % 10 == 0 or i == total_files - 1:
1014 - progress = 20 + (i + 1) / total_files * 70 # 20-90%
1015 - yield {
1016 - "stage": "backup",
1017 - "message": f"Adding file: {file_info['path']}",
1018 - "progress": int(progress),
1019 - "completed": False,
1020 - "current_file": i + 1,
1021 - "total_files": total_files,
1022 - "file_path": file_info["path"]
1023 - }
1024 - except Exception as e:
1025 - yield {
1026 - "stage": "warning",
1027 - "message": f"Failed to backup file: {file_info['path']} - {str(e)}",
1028 - "progress": int(20 + (i + 1) / total_files * 70),
1029 - "completed": False,
1030 - "warning": True
1031 - }
1032 -
1033 - # Step 4: Calculate final checksum
1034 - yield {
1035 - "stage": "finalization",
1036 - "message": "Calculating backup checksum...",
1037 - "progress": 95,
1038 - "completed": False
1039 - }
1040 -
1041 - backup_checksum = self._calculate_backup_checksum(zip_path)
1042 -
1043 - # Step 5: Complete
1044 - yield {
1045 - "stage": "completed",
1046 - "message": "Backup created successfully",
1047 - "progress": 100,
1048 - "completed": True,
1049 - "success": True,
1050 - "backup_path": zip_path,
1051 - "backup_checksum": backup_checksum,
1052 - "total_files": total_files,
1053 - "backup_size": os.path.getsize(zip_path)
1054 - }
1055 -
1056 - except Exception as e:
1057 - yield {
1058 - "stage": "error",
1059 - "message": f"Backup failed: {str(e)}",
1060 - "progress": 0,
1061 - "completed": True,
1062 - "error": True
1063 - }
1064 -
1065 - async def restore_backup(self, backup_file, restore_patterns: str, overwrite_policy: str = "overwrite") -> Dict[str, Any]:
1066 - """Restore files from backup archive"""
1067 -
1068 - # Save uploaded file temporarily
1069 - temp_dir = tempfile.mkdtemp()
1070 - temp_file = os.path.join(temp_dir, "backup.zip")
1071 -
1072 - restored_files = []
1073 - skipped_files = []
1074 - errors = []
1075 -
1076 - try:
1077 - backup_file.save(temp_file)
1078 -
1079 - # Parse restore patterns if provided
1080 - if restore_patterns.strip():
1081 - pattern_lines = [line.strip() for line in restore_patterns.split('\n')
1082 - if line.strip() and not line.strip().startswith('#')]
1083 - spec = PathSpec.from_lines(GitWildMatchPattern, pattern_lines) if pattern_lines else None
1084 - else:
1085 - spec = None
1086 -
1087 - with zipfile.ZipFile(temp_file, 'r') as zipf:
1088 - # Read metadata
1089 - if "metadata.json" in zipf.namelist():
1090 - metadata_content = zipf.read("metadata.json").decode('utf-8')
1091 - metadata = json.loads(metadata_content)
1092 -
1093 - # Process each file in archive
1094 - for archive_path in zipf.namelist():
1095 - if archive_path == "metadata.json":
1096 - continue
1097 -
1098 - # Check if file matches restore patterns
1099 - if spec and not spec.match_file(archive_path):
1100 - skipped_files.append({
1101 - "path": archive_path,
1102 - "reason": "not_matched_by_pattern"
1103 - })
1104 - continue
1105 -
1106 - # Determine target path
1107 - target_path = self._resolve_path("/" + archive_path)
1108 -
1109 - try:
1110 - # Handle overwrite policy
1111 - if os.path.exists(target_path):
1112 - if overwrite_policy == "skip":
1113 - skipped_files.append({
1114 - "path": archive_path,
1115 - "reason": "file_exists_skip_policy"
1116 - })
1117 - continue
1118 - elif overwrite_policy == "backup":
1119 - backup_path = f"{target_path}.backup.{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}"
1120 - shutil.move(target_path, backup_path)
1121 -
1122 - # Create target directory if needed
1123 - target_dir = os.path.dirname(target_path)
1124 - os.makedirs(target_dir, exist_ok=True)
1125 -
1126 - # Extract file
1127 - with zipf.open(archive_path) as source, open(target_path, 'wb') as target:
1128 - shutil.copyfileobj(source, target)
1129 -
1130 - restored_files.append({
1131 - "archive_path": archive_path,
1132 - "target_path": target_path,
1133 - "status": "restored"
1134 - })
1135 -
1136 - except Exception as e:
1137 - errors.append({
1138 - "path": archive_path,
1139 - "error": str(e)
1140 - })
1141 -
1142 - return {
1143 - "restored_files": restored_files,
1144 - "skipped_files": skipped_files,
1145 - "errors": errors
1146 - }
1147 -
1148 - except Exception as e:
1149 - raise Exception(f"Error restoring backup: {str(e)}")
1150 - finally:
1151 - # Cleanup
1152 - if os.path.exists(temp_file):
1153 - os.remove(temp_file)
1154 - if os.path.exists(temp_dir):
1155 - os.rmdir(temp_dir)
1156 -
1157 - async def preview_restore(self, backup_file, restore_patterns: str) -> Dict[str, Any]:
1158 - """Preview which files would be restored based on patterns"""
1159 -
1160 - # Save uploaded file temporarily
1161 - temp_dir = tempfile.mkdtemp()
1162 - temp_file = os.path.join(temp_dir, "backup.zip")
1163 -
1164 - files_to_restore = []
1165 - skipped_files = []
1166 -
1167 - try:
1168 - backup_file.save(temp_file)
1169 -
1170 - # Parse restore patterns if provided
1171 - if restore_patterns.strip():
1172 - pattern_lines = [line.strip() for line in restore_patterns.split('\n')
1173 - if line.strip() and not line.strip().startswith('#')]
1174 - spec = PathSpec.from_lines(GitWildMatchPattern, pattern_lines) if pattern_lines else None
1175 - else:
1176 - spec = None
1177 -
1178 - with zipfile.ZipFile(temp_file, 'r') as zipf:
1179 - # Read metadata for context
1180 - metadata = {}
1181 - if "metadata.json" in zipf.namelist():
1182 - metadata_content = zipf.read("metadata.json").decode('utf-8')
1183 - metadata = json.loads(metadata_content)
1184 -
1185 - # Process each file in archive
1186 - for archive_path in zipf.namelist():
1187 - if archive_path == "metadata.json":
1188 - continue
1189 -
1190 - # Check if file matches restore patterns
1191 - if spec:
1192 - if spec.match_file(archive_path):
1193 - files_to_restore.append({
1194 - "path": archive_path,
1195 - "target_path": self._resolve_path("/" + archive_path),
1196 - "action": "restore"
1197 - })
1198 - else:
1199 - skipped_files.append({
1200 - "path": archive_path,
1201 - "reason": "not_matched_by_pattern"
1202 - })
1203 - else:
1204 - # No patterns specified, restore all files
1205 - files_to_restore.append({
1206 - "path": archive_path,
1207 - "target_path": self._resolve_path("/" + archive_path),
1208 - "action": "restore"
1209 - })
1210 -
1211 - return {
1212 - "files": files_to_restore,
1213 - "skipped_files": skipped_files,
1214 - "total_count": len(files_to_restore),
1215 - "skipped_count": len(skipped_files)
1216 - }
1217 -
1218 - except Exception as e:
1219 - raise Exception(f"Error previewing restore: {str(e)}")
1220 - finally:
1221 - # Cleanup
1222 - if os.path.exists(temp_file):
1223 - os.remove(temp_file)
1224 - if os.path.exists(temp_dir):
1225 - os.rmdir(temp_dir)
1226 -```
1227 -
1228 -### 4. Dependencies
1229 -
1230 -#### Required Python Packages
1231 -Add to `requirements.txt`:
1232 -```
1233 -pathspec>=0.10.0 # For gitignore-style pattern matching
1234 -psutil>=5.8.0 # For system information collection
1235 -```
1236 -
1237 -#### Agent Zero Internal Dependencies
1238 -The backup system requires these Agent Zero helper modules:
1239 -- `python.helpers.git` - For version detection using git.get_git_info() (consistent with run_ui.py)
1240 -- `python.helpers.files` - For file operations and path resolution
1241 -- `python.helpers.runtime` - For development/production mode detection
1242 -
1243 -#### Installation Command
1244 -```bash
1245 -pip install pathspec psutil
1246 -```
1247 -
1248 -### 5. Error Handling
1249 -
1250 -#### Integration with Agent Zero Error System
1251 -The backup system integrates with Agent Zero's existing error handling infrastructure:
1252 -
1253 -```python
1254 -from python.helpers.errors import format_error
1255 -from python.helpers.print_style import PrintStyle
1256 -
1257 -# Follow Agent Zero's error handling patterns
1258 -try:
1259 - result = await backup_operation()
1260 - return {"success": True, "data": result}
1261 -except Exception as e:
1262 - error_message = format_error(e)
1263 - PrintStyle.error(f"Backup error: {error_message}")
1264 - return {"success": False, "error": error_message}
1265 -```
1266 -
1267 -#### Common Error Scenarios
1268 -1. **Invalid Patterns**: Malformed glob patterns
1269 -2. **Permission Errors**: Files/directories not accessible
1270 -3. **Disk Space**: Insufficient space for backup creation
1271 -4. **Invalid Archives**: Corrupted or invalid backup files
1272 -5. **Path Conflicts**: Files outside allowed directories
1273 -
1274 -#### Error Response Format
1275 -```python
1276 -{
1277 - "success": False,
1278 - "error": "Human-readable error message",
1279 - "error_code": "BACKUP_PATTERN_INVALID", # Optional machine-readable code
1280 - "details": { # Optional additional details
1281 - "invalid_patterns": ["pattern1", "pattern2"],
1282 - "suggestion": "Check pattern syntax"
1283 - }
1284 -}
1285 -```
1286 -
1287 -### 6. Security Considerations
1288 -
1289 -#### Path Security
1290 -- Validate all paths to prevent directory traversal attacks
1291 -- Restrict backups to predefined base directories (/a0, /root)
1292 -- Sanitize file names in archives
1293 -- Implement file size limits for uploads/downloads
1294 -
1295 -#### Authentication
1296 -- All endpoints require authentication (`requires_auth = True`)
1297 -- All endpoints require loopback (`requires_loopback = True`)
1298 -- No API key access for security
1299 -
1300 -#### File System Protection
1301 -- Read-only access to system directories outside allowed paths
1302 -- Size limits for backup archives
1303 -- Timeout limits for backup operations
1304 -- Temporary file cleanup
1305 -
1306 -### 7. Performance Considerations
1307 -
1308 -#### File Processing
1309 -- Limit number of files in test/preview operations (max_files parameter)
1310 -- Stream file processing for large archives
1311 -- Implement progress tracking for large operations
1312 -- Use temporary directories for staging
1313 -
1314 -#### Memory Management
1315 -- Stream zip file creation to avoid memory issues
1316 -- Process files individually rather than loading all in memory
1317 -- Clean up temporary files promptly
1318 -- Implement timeout limits for long operations
1319 -
1320 -### 8. Configuration
1321 -
1322 -#### Default Configuration
1323 -```python
1324 -BACKUP_CONFIG = {
1325 - "max_files_preview": 1000,
1326 - "max_backup_size": 1024 * 1024 * 1024, # 1GB
1327 - "max_upload_size": 1024 * 1024 * 1024, # 1GB
1328 - "operation_timeout": 300, # 5 minutes
1329 - "temp_cleanup_interval": 3600, # 1 hour
1330 - "allowed_base_paths": ["/a0", "/root"]
1331 -}
1332 -```
1333 -
1334 -#### Future Integration Opportunities
1335 -**Task Scheduler Integration:**
1336 -Agent Zero's existing task scheduler could be extended to support automated backups:
1337 -
1338 -```python
1339 -# Potential future enhancement - scheduled backups
1340 -{
1341 - "name": "auto_backup_daily",
1342 - "type": "scheduled",
1343 - "schedule": "0 2 * * *", # Daily at 2 AM
1344 - "tool_name": "backup_create",
1345 - "tool_args": {
1346 - "patterns": "default_patterns",
1347 - "backup_name": "auto_backup_{date}"
1348 - }
1349 -}
1350 -```
1351 -
1352 -## Enhanced Metadata Structure and Restore Workflow
1353 -
1354 -### Version Detection Implementation
1355 -The backup system uses the same version detection method as Agent Zero's main UI:
1356 -
1357 -```python
1358 -def _get_agent_zero_version(self) -> str:
1359 - """Get current Agent Zero version"""
1360 - try:
1361 - # Get version from git info (same as run_ui.py)
1362 - gitinfo = git.get_git_info()
1363 - return gitinfo.get("version", "development")
1364 - except:
1365 - return "unknown"
1366 -```
1367 -
1368 -This ensures consistency between the backup metadata and the main application version reporting.
1369 -
1370 -### Metadata.json Format
1371 -The backup archive includes a comprehensive `metadata.json` file with the following structure:
1372 -
1373 -```json
1374 -{
1375 - "agent_zero_version": "version",
1376 - "timestamp": "ISO datetime",
1377 - "backup_name": "user-defined name",
1378 - "include_hidden": boolean,
1379 -
1380 - "include_patterns": [
1381 - "/a0/knowledge/**",
1382 - "/a0/instruments/**",
1383 - "/a0/memory/**",
1384 - "/a0/.env",
1385 - "/a0/tmp/settings.json"
1386 - ],
1387 - "exclude_patterns": [
1388 - "/a0/knowledge/default/**",
1389 - "/a0/instruments/default/**",
1390 - "/a0/memory/embeddings/**"
1391 - ],
1392 -
1393 - "system_info": { /* platform, architecture, etc. */ },
1394 - "environment_info": { /* user, timezone, paths, etc. */ },
1395 - "backup_author": "user@hostname",
1396 - "backup_config": {
1397 - "default_patterns": "system defaults",
1398 - "include_hidden": boolean,
1399 - "compression_level": 6,
1400 - "integrity_check": true
1401 - },
1402 -
1403 - "files": [ /* file list with checksums */ ],
1404 - "total_files": count,
1405 - "backup_size": bytes,
1406 - "backup_checksum": "sha256"
1407 -}
1408 -```
1409 -
1410 -### Restore Workflow
1411 -1. **Upload Archive**: User uploads backup.zip file
1412 -2. **Load Metadata**: System extracts and parses metadata.json
1413 -3. **Display Metadata**: Complete metadata.json shown in ACE JSON editor
1414 -4. **User Editing**: User can modify include_patterns and exclude_patterns arrays directly
1415 -5. **Preview Changes**: System shows which files will be restored based on current metadata
1416 -6. **Execute Restore**: Files restored according to final metadata configuration
1417 -
1418 -### JSON Metadata Editing Benefits
1419 -- **Single Source of Truth**: metadata.json is the authoritative configuration
1420 -- **Direct Editing**: Users edit JSON arrays directly in ACE editor
1421 -- **Full Control**: Access to all metadata properties, not just patterns
1422 -- **Validation**: JSON syntax validation and array structure validation
1423 -- **Transparency**: Users see exactly what will be used for restore
1424 -
1425 -## Comprehensive Enhancement Summary
1426 -
1427 -### Enhanced Metadata Structure
1428 -The backup metadata has been significantly enhanced to include:
1429 -- **System Information**: Platform, architecture, Python version, CPU count, memory, disk usage
1430 -- **Environment Details**: User, timezone, working directory, runtime mode, Agent Zero root path
1431 -- **Backup Author**: System identifier (user@hostname) for backup tracking
1432 -- **File Checksums**: SHA-256 hashes for all backed up files for integrity verification
1433 -- **Backup Statistics**: Total files, directories, sizes with verification methods
1434 -- **Compatibility Data**: Agent Zero version and environment for restoration validation
1435 -
1436 -### Smart File Management
1437 -- **Grouped File Preview**: Organize files by directory structure with depth limitation (max 3 levels)
1438 -- **Smart Grouping**: Show directory hierarchies with expandable file counts
1439 -- **Search and Filter**: Real-time filtering by file name or path fragments
1440 -- **Performance Optimization**: Limit preview files (1000 max) and displayed files (50 per group) for UI responsiveness
1441 -
1442 -### Real-time Progress Streaming
1443 -- **Server-Sent Events**: Live backup progress updates via `/backup_progress_stream` endpoint
1444 -- **Multi-stage Progress**: Discovery → Checksums → Backup → Finalization with percentage tracking
1445 -- **File-by-file Updates**: Real-time display of current file being processed
1446 -- **Error Handling**: Graceful error reporting and warning collection during backup process
1447 -
1448 -### Advanced API Endpoints
1449 -1. **`/backup_preview_grouped`**: Get smart file groupings with depth control and search
1450 -2. **`/backup_progress_stream`**: Stream real-time backup progress via SSE
1451 -3. **`/backup_restore_preview`**: Preview restore operations with pattern filtering
1452 -4. **Enhanced `/backup_inspect`**: Return comprehensive metadata with system information
1453 -
1454 -### System Information Collection
1455 -- **Platform Detection**: OS, architecture, Python version, hostname
1456 -- **Resource Information**: CPU count, memory, disk usage via psutil (converted to strings for JSON consistency)
1457 -- **Environment Capture**: User, timezone, paths, runtime mode
1458 -- **Version Integration**: Uses git.get_git_info() for consistent version detection with main application
1459 -- **Integrity Verification**: SHA-256 checksums for individual files and complete backup
1460 -
1461 -### Security and Reliability Enhancements
1462 -- **Integrity Verification**: File-level and backup-level checksum validation
1463 -- **Comprehensive Logging**: Detailed progress tracking and error collection
1464 -- **Path Security**: Enhanced validation with system information context
1465 -- **Backup Validation**: Version compatibility checking and environment verification
1466 -
1467 -This enhanced backend specification provides a production-ready, comprehensive backup and restore system with advanced metadata tracking, real-time progress monitoring, and intelligent file management capabilities, all while maintaining Agent Zero's architectural patterns and security standards.
1468 -
1469 -### Implementation Status Updates
1470 -
1471 -#### ✅ COMPLETED: Core BackupService Implementation
1472 -- **Git Version Integration**: Updated to use `git.get_git_info()` consistent with `run_ui.py`
1473 -- **Type Safety**: Fixed psutil return values to be strings for JSON metadata consistency
1474 -- **Code Quality**: All linting errors resolved, proper import structure
1475 -- **Testing Verified**: BackupService initializes correctly and detects Agent Zero root paths
1476 -- **Dependencies Added**: pathspec>=0.10.0 for pattern matching, psutil>=5.8.0 for system info
1477 -- **Git Helper Integration**: Uses python.helpers.git.get_git_info() for version detection consistency
1478 -
1479 -#### Next Implementation Phase: API Endpoints
1480 -Ready to implement the 8 API endpoints:
1481 -1. `backup_test.py` - Pattern testing and file preview
1482 -2. `backup_create.py` - Archive creation and download
1483 -3. `backup_restore.py` - File restoration from archive
1484 -4. `backup_inspect.py` - Archive metadata inspection
1485 -5. `backup_get_defaults.py` - Fetch default patterns
1486 -6. `backup_restore_preview.py` - Preview restore patterns
1487 -7. `backup_preview_grouped.py` - Smart directory grouping
1488 -8. `backup_progress_stream.py` - Real-time progress streaming
1489 -
1490 -## Implementation Cleanup and Final Status
1491 -
1492 -### ✅ **COMPLETED CLEANUP (December 2024)**
1493 -
1494 -#### **Removed Unused Components:**
1495 -- ❌ **`backup_download.py`** - Functionality moved to `backup_create` (direct download)
1496 -- ❌ **`backup_progress_stream.py`** - Not implemented in frontend, overengineered
1497 -- ❌ **`_calculate_file_checksums()` method** - Dead code, checksums not properly used
1498 -- ❌ **`_calculate_backup_checksum()` method** - Dead code, never called
1499 -- ❌ **`hashlib` import** - No longer needed after checksum removal
1500 -
1501 -#### **Simplified BackupService:**
1502 -- ✅ **Removed checksum calculation** - Was calculated but not properly used, overcomplicating the code
1503 -- ✅ **Streamlined metadata** - Removed unused integrity verification fields
1504 -- ✅ **Fixed `_count_directories()` method** - Had return statement in wrong place
1505 -- ✅ **Cleaner error handling** - Removed unnecessary warning outputs
1506 -
1507 -#### **Enhanced Hidden File Logic:**
1508 -The most critical fix was implementing proper explicit pattern handling:
1509 -
1510 -```python
1511 -# NEW: Enhanced hidden file logic
1512 -def _get_explicit_patterns(self, include_patterns: List[str]) -> set[str]:
1513 - """Extract explicit (non-wildcard) patterns that should always be included"""
1514 - explicit_patterns = set()
1515 -
1516 - for pattern in include_patterns:
1517 - # If pattern doesn't contain wildcards, it's explicit
1518 - if '*' not in pattern and '?' not in pattern:
1519 - # Remove leading slash for comparison
1520 - explicit_patterns.add(pattern.lstrip('/'))
1521 -
1522 - # Also add parent directories as explicit (so hidden dirs can be traversed)
1523 - path_parts = pattern.lstrip('/').split('/')
1524 - for i in range(1, len(path_parts)):
1525 - parent_path = '/'.join(path_parts[:i])
1526 - explicit_patterns.add(parent_path)
1527 -
1528 - return explicit_patterns
1529 -
1530 -# FIXED: Hidden file filtering now respects explicit patterns
1531 -if not include_hidden and file.startswith('.'):
1532 - if not self._is_explicitly_included(pattern_path, explicit_patterns):
1533 - continue # Only exclude hidden files discovered via wildcards
1534 -```
1535 -
1536 -#### **Final API Endpoint Set (6 endpoints):**
1537 -1. ✅ **`backup_get_defaults`** - Get default metadata configuration
1538 -2. ✅ **`backup_test`** - Test patterns and preview files (dry run)
1539 -3. ✅ **`backup_preview_grouped`** - Get grouped file preview for UI
1540 -4. ✅ **`backup_create`** - Create and download backup archive
1541 -5. ✅ **`backup_inspect`** - Inspect uploaded backup metadata
1542 -6. ✅ **`backup_restore_preview`** - Preview restore operation
1543 -7. ✅ **`backup_restore`** - Execute restore operation
1544 -
1545 -### **Critical Issue Fixed: Hidden Files**
1546 -
1547 -**Problem:** When `include_hidden=false`, the system was excluding ALL hidden files, even when they were explicitly specified in patterns like `/a0/.env`.
1548 -
1549 -**Solution:** Implemented explicit pattern detection that distinguishes between:
1550 -- **Explicit patterns** (like `/a0/.env`) - Always included regardless of `include_hidden` setting
1551 -- **Wildcard discoveries** (like `/a0/*`) - Respect the `include_hidden` setting
1552 -
1553 -**Result:** Critical files like `.env` are now properly backed up when explicitly specified, ensuring Agent Zero configurations are preserved.
1554 -
1555 -### **Implementation Status: ✅ PRODUCTION READY**
1556 -
1557 -The backup system is now:
1558 -- **Simplified**: Removed unnecessary complexity and dead code
1559 -- **Reliable**: Fixed critical hidden file handling
1560 -- **Efficient**: No unnecessary checksum calculations
1561 -- **Clean**: Proper error handling and type safety
1562 -- **Complete**: Full backup and restore functionality working
1563 -
1564 -**Key Benefits of Cleanup:**
1565 -- ✅ **Simpler maintenance** - Less code to maintain and debug
1566 -- ✅ **Better performance** - No unnecessary checksum calculations
1567 -- ✅ **Correct behavior** - Hidden files now work as expected
1568 -- ✅ **Cleaner API** - Only endpoints that are actually used
1569 -- ✅ **Better reliability** - Removed complex features that weren't properly implemented
1570 -
1571 -The Agent Zero backup system is now production-ready and battle-tested! 🚀
1572 -
1573 -## ✅ **FINAL STATUS: ACE EDITOR STATE GUARANTEE COMPLETED (December 2024)**
1574 -
1575 -### **Goal Achievement Verification**
1576 -
1577 -The primary goal has been successfully achieved: **All metadata.json operations in GUI use the ACE editor state, not original archive metadata, giving users complete control to edit and execute exactly what's defined in the editor.**
1578 -
1579 -#### **✅ Archive metadata.json Usage** (MINIMAL - only technical requirements):
1580 -```python
1581 -# ONLY used for:
1582 -# 1. Initial ACE editor preload (backup_inspect API)
1583 -original_backup_metadata = json.loads(metadata_content)
1584 -metadata["include_patterns"] = original_backup_metadata.get("include_patterns", [])
1585 -metadata["exclude_patterns"] = original_backup_metadata.get("exclude_patterns", [])
1586 -
1587 -# 2. Path translation for cross-system compatibility
1588 -environment_info = original_backup_metadata.get("environment_info", {})
1589 -backed_up_agent_root = environment_info.get("agent_zero_root", "")
1590 -```
1591 -
1592 -#### **✅ ACE editor metadata Usage** (EVERYTHING ELSE):
1593 -```python
1594 -# Used for ALL user-controllable operations:
1595 -backup_metadata = user_edited_metadata if user_edited_metadata else original_backup_metadata
1596 -
1597 -# 1. File pattern matching for restore
1598 -restore_include_patterns = backup_metadata.get("include_patterns", [])
1599 -restore_exclude_patterns = backup_metadata.get("exclude_patterns", [])
1600 -
1601 -# 2. Clean before restore operations
1602 -files_to_delete = await self._find_files_to_clean_with_user_metadata(backup_metadata, original_backup_metadata)
1603 -
1604 -# 3. All user preferences and settings
1605 -include_hidden = backup_metadata.get("include_hidden", False)
1606 -```
1607 -
1608 -### **Implementation Architecture**
1609 -
1610 -#### **Hybrid Approach - Perfect Balance:**
1611 -- **✅ User Control**: ACE editor content drives all restore operations
1612 -- **✅ Technical Compatibility**: Original metadata enables cross-system path translation
1613 -- **✅ Complete Transparency**: Users see and control exactly what will be executed
1614 -- **✅ System Intelligence**: Automatic path translation preserves functionality
1615 -
1616 -#### **API Layer Integration:**
1617 -```python
1618 -# Both preview and restore APIs follow same pattern:
1619 -class BackupRestorePreview(ApiHandler):
1620 - async def process(self, input: dict, request: Request) -> dict | Response:
1621 - # Get user-edited metadata from ACE editor
1622 - metadata = json.loads(metadata_json)
1623 -
1624 - # Pass user metadata to service layer
1625 - result = await backup_service.preview_restore(
1626 - backup_file=backup_file,
1627 - restore_include_patterns=metadata.get("include_patterns", []),
1628 - restore_exclude_patterns=metadata.get("exclude_patterns", []),
1629 - user_edited_metadata=metadata # ← ACE editor content
1630 - )
1631 -```
1632 -
1633 -#### **Service Layer Implementation:**
1634 -```python
1635 -# Service methods intelligently use both metadata sources:
1636 -async def preview_restore(self, user_edited_metadata: Optional[Dict[str, Any]] = None):
1637 - # Read original metadata from archive
1638 - original_backup_metadata = json.loads(metadata_content)
1639 -
1640 - # Use ACE editor metadata for operations
1641 - backup_metadata = user_edited_metadata if user_edited_metadata else original_backup_metadata
1642 -
1643 - # User metadata drives pattern matching
1644 - files_to_restore = await self._process_with_user_patterns(backup_metadata)
1645 -
1646 - # Original metadata enables path translation
1647 - target_path = self._translate_restore_path(archive_path, original_backup_metadata)
1648 -```
1649 -
1650 -### **Dead Code Cleanup Results**
1651 -
1652 -#### **✅ Removed Unused Method:**
1653 -- **`_find_files_to_clean()` method** (39 lines) - Replaced by `_find_files_to_clean_with_user_metadata()`
1654 -- **Functionality**: Was using original archive metadata instead of user-edited metadata
1655 -- **Replacement**: New method properly uses ACE editor content for clean operations
1656 -
1657 -#### **✅ Method Comparison:**
1658 -```python
1659 -# OLD (REMOVED): Used original archive metadata
1660 -async def _find_files_to_clean(self, backup_metadata: Dict[str, Any]):
1661 - original_include_patterns = backup_metadata.get("include_patterns", []) # ← Archive metadata
1662 - # ... 39 lines of implementation
1663 -
1664 -# NEW (ACTIVE): Uses ACE editor metadata
1665 -async def _find_files_to_clean_with_user_metadata(self, user_metadata: Dict[str, Any], original_metadata: Dict[str, Any]):
1666 - user_include_patterns = user_metadata.get("include_patterns", []) # ← ACE editor metadata
1667 - # Translation only uses original_metadata for environment_info
1668 -```
1669 -
1670 -### **User Experience Flow**
1671 -
1672 -1. **Upload Archive** → Original metadata.json extracted
1673 -2. **ACE Editor Preload** → Original patterns shown as starting point
1674 -3. **User Editing** → Complete freedom to modify patterns, settings
1675 -4. **Preview Operation** → Uses current ACE editor content
1676 -5. **Execute Restore** → Uses final ACE editor content
1677 -6. **Path Translation** → Automatic system compatibility (transparent to user)
1678 -
1679 -### **Technical Benefits Achieved**
1680 -
1681 -#### **✅ Complete User Control:**
1682 -- Users can edit any pattern in the ACE editor
1683 -- Changes immediately reflected in preview operations
1684 -- Execute button runs exactly what's shown in editor
1685 -- No hidden operations using different metadata
1686 -
1687 -#### **✅ Cross-System Compatibility:**
1688 -- Path translation preserves technical functionality
1689 -- Users don't need to manually adjust paths
1690 -- Works seamlessly between different Agent Zero installations
1691 -- Maintains backup portability across environments
1692 -
1693 -#### **✅ Clean Architecture:**
1694 -- Single source of truth: ACE editor content
1695 -- Clear separation of concerns: user control vs technical requirements
1696 -- Eliminated dead code and simplified maintenance
1697 -- Consistent behavior between preview and execution
1698 -
1699 -### **Final Status: ✅ PRODUCTION READY**
1700 -
1701 -The Agent Zero backup system now provides:
1702 -- **✅ Complete user control** via ACE editor state
1703 -- **✅ Cross-system compatibility** through intelligent path translation
1704 -- **✅ Clean, maintainable code** with dead code eliminated
1705 -- **✅ Transparent operations** with full user visibility
1706 -- **✅ Production reliability** with comprehensive error handling
1707 -
1708 -**The backup system perfectly balances user control with technical functionality!** 🎯
docs/development/designs/backup-specification-frontend.md deleted
-1663
@@ -1,1663 +0,0 @@
1 -# Agent Zero Backup/Restore Frontend Specification
2 -
3 -## Overview
4 -This specification defines the frontend implementation for Agent Zero's backup and restore functionality, providing an intuitive user interface with a dedicated "backup" tab in the settings system and following established Alpine.js patterns. The backup functionality gets its own tab for better organization and user experience.
5 -
6 -## Frontend Architecture
7 -
8 -### 1. Settings Integration
9 -
10 -#### Settings Modal Enhancement
11 -Update `webui/js/settings.js` to handle backup/restore button clicks in the dedicated backup tab:
12 -
13 -```javascript
14 -// Add to handleFieldButton method (following MCP servers pattern)
15 -async handleFieldButton(field) {
16 - console.log(`Button clicked: ${field.id}`);
17 -
18 - if (field.id === "mcp_servers_config") {
19 - openModal("settings/mcp/client/mcp-servers.html");
20 - } else if (field.id === "backup_create") {
21 - openModal("settings/backup/backup.html");
22 - } else if (field.id === "backup_restore") {
23 - openModal("settings/backup/restore.html");
24 - }
25 -}
26 -```
27 -
28 -### 2. Component Structure
29 -
30 -#### Directory Structure
31 -```
32 -webui/components/settings/backup/
33 -├── backup.html # Backup creation modal
34 -├── restore.html # Restore modal
35 -└── backup-store.js # Shared store for both modals
36 -```
37 -
38 -**Note**: The backup functionality is accessed through a dedicated "backup" tab in the settings interface, providing users with easy access to backup and restore operations without cluttering other settings areas.
39 -
40 -#### Enhanced Metadata Structure
41 -The backup system uses a comprehensive `metadata.json` file that includes:
42 -- **Pattern Arrays**: Separate `include_patterns[]` and `exclude_patterns[]` for granular control
43 -- **System Information**: Platform, environment, and version details
44 -- **Direct JSON Editing**: Users edit the metadata.json directly in ACE JSON editor
45 -- **Single Source of Truth**: No pattern string conversions, metadata.json is authoritative
46 -
47 -### 3. Backup Modal Component
48 -
49 -#### File: `webui/components/settings/backup/backup.html`
50 -```html
51 -<html>
52 -<head>
53 - <title>Create Backup</title>
54 - <script type="module">
55 - import { store } from "/components/settings/backup/backup-store.js";
56 - </script>
57 -</head>
58 -<body>
59 - <div x-data>
60 - <template x-if="$store.backupStore">
61 - <div x-init="$store.backupStore.initBackup()" x-destroy="$store.backupStore.onClose()">
62 -
63 - <!-- Header with buttons (following MCP servers pattern) -->
64 - <h3>Backup Configuration JSON
65 - <button class="btn slim" style="margin-left: 0.5em;"
66 - @click="$store.backupStore.formatJson()">Format</button>
67 - <button class="btn slim" style="margin-left: 0.5em;"
68 - @click="$store.backupStore.resetToDefaults()">Reset</button>
69 - <button class="btn slim" style="margin-left: 0.5em;"
70 - @click="$store.backupStore.dryRun()" :disabled="$store.backupStore.loading">Dry Run</button>
71 - <button class="btn slim primary" style="margin-left: 0.5em;"
72 - @click="$store.backupStore.createBackup()" :disabled="$store.backupStore.loading">Create Backup</button>
73 - </h3>
74 -
75 - <!-- JSON Editor (upper part) -->
76 - <div id="backup-metadata-editor"></div>
77 -
78 - <!-- File Operations Display (lower part) -->
79 - <h3 id="backup-operations">File Operations</h3>
80 -
81 - <!-- File listing textarea -->
82 - <div class="file-operations-container">
83 - <textarea id="backup-file-list"
84 - x-model="$store.backupStore.fileOperationsLog"
85 - readonly
86 - placeholder="File operations will be displayed here..."></textarea>
87 - </div>
88 -
89 - <!-- Loading indicator -->
90 - <div x-show="$store.backupStore.loading" class="backup-loading">
91 - <span x-text="$store.backupStore.loadingMessage || 'Processing...'"></span>
92 - </div>
93 -
94 - <!-- Error display -->
95 - <div x-show="$store.backupStore.error" class="backup-error">
96 - <span x-text="$store.backupStore.error"></span>
97 - </div>
98 -
99 - </div>
100 - </template>
101 - </div>
102 -
103 - <style>
104 - .backup-loading {
105 - width: 100%;
106 - text-align: center;
107 - margin-top: 2rem;
108 - margin-bottom: 2rem;
109 - color: var(--c-text-secondary);
110 - }
111 -
112 - #backup-metadata-editor {
113 - width: 100%;
114 - height: 25em;
115 - }
116 -
117 - .file-operations-container {
118 - margin-top: 0.5em;
119 - margin-bottom: 1em;
120 - }
121 -
122 - #backup-file-list {
123 - width: 100%;
124 - height: 15em;
125 - font-family: monospace;
126 - font-size: 0.85em;
127 - background: var(--c-bg-primary);
128 - color: var(--c-text-primary);
129 - border: 1px solid var(--c-border);
130 - border-radius: 4px;
131 - padding: 0.5em;
132 - resize: vertical;
133 - }
134 -
135 - .backup-error {
136 - color: var(--c-error);
137 - margin: 0.5rem 0;
138 - padding: 0.5rem;
139 - background: var(--c-error-bg);
140 - border-radius: 4px;
141 - }
142 - </style>
143 -</body>
144 -</html>
145 -```
146 -
147 -### 4. Restore Modal Component
148 -
149 -#### File: `webui/components/settings/backup/restore.html`
150 -```html
151 -<html>
152 -<head>
153 - <title>Restore Backup</title>
154 - <script type="module">
155 - import { store } from "/components/settings/backup/backup-store.js";
156 - </script>
157 -</head>
158 -<body>
159 - <div x-data>
160 - <template x-if="$store.backupStore">
161 - <div x-init="$store.backupStore.initRestore()" x-destroy="$store.backupStore.onClose()">
162 -
163 - <!-- File Upload Section -->
164 - <div class="upload-section">
165 - <label for="backup-file" class="upload-label">
166 - Select Backup File (.zip)
167 - </label>
168 - <input type="file" id="backup-file" accept=".zip"
169 - @change="$store.backupStore.handleFileUpload($event)">
170 - </div>
171 -
172 - <!-- Header with buttons (following MCP servers pattern) -->
173 - <h3 x-show="$store.backupStore.backupMetadata">Restore Configuration JSON
174 - <button class="btn slim" style="margin-left: 0.5em;"
175 - @click="$store.backupStore.formatJson()">Format</button>
176 - <button class="btn slim" style="margin-left: 0.5em;"
177 - @click="$store.backupStore.resetToOriginalMetadata()">Reset</button>
178 - <button class="btn slim" style="margin-left: 0.5em;"
179 - @click="$store.backupStore.dryRun()" :disabled="$store.backupStore.loading">Dry Run</button>
180 - <button class="btn slim primary" style="margin-left: 0.5em;"
181 - @click="$store.backupStore.performRestore()" :disabled="$store.backupStore.loading">Restore Files</button>
182 - </h3>
183 -
184 - <!-- JSON Editor (upper part) -->
185 - <div x-show="$store.backupStore.backupMetadata" id="restore-metadata-editor"></div>
186 -
187 - <!-- File Operations Display (lower part) -->
188 - <h3 x-show="$store.backupStore.backupMetadata" id="restore-operations">File Operations</h3>
189 -
190 - <!-- File listing textarea -->
191 - <div x-show="$store.backupStore.backupMetadata" class="file-operations-container">
192 - <textarea id="restore-file-list"
193 - x-model="$store.backupStore.fileOperationsLog"
194 - readonly
195 - placeholder="File operations will be displayed here..."></textarea>
196 - </div>
197 -
198 - <!-- Overwrite Policy -->
199 - <div x-show="$store.backupStore.backupMetadata" class="overwrite-policy">
200 - <h4>File Conflict Policy</h4>
201 - <label class="radio-option">
202 - <input type="radio" name="overwrite" value="overwrite"
203 - x-model="$store.backupStore.overwritePolicy">
204 - <span>Overwrite existing files</span>
205 - </label>
206 - <label class="radio-option">
207 - <input type="radio" name="overwrite" value="skip"
208 - x-model="$store.backupStore.overwritePolicy">
209 - <span>Skip existing files</span>
210 - </label>
211 - <label class="radio-option">
212 - <input type="radio" name="overwrite" value="backup"
213 - x-model="$store.backupStore.overwritePolicy">
214 - <span>Backup existing files (.backup.timestamp)</span>
215 - </label>
216 - </div>
217 -
218 - <!-- Loading indicator -->
219 - <div x-show="$store.backupStore.loading" class="restore-loading">
220 - <span x-text="$store.backupStore.loadingMessage || 'Processing...'"></span>
221 - </div>
222 -
223 - <!-- Error display -->
224 - <div x-show="$store.backupStore.error" class="restore-error">
225 - <span x-text="$store.backupStore.error"></span>
226 - </div>
227 -
228 - <!-- Success display -->
229 - <div x-show="$store.backupStore.restoreResult" class="restore-result">
230 - <h4>Restore Complete</h4>
231 - <div class="result-stats">
232 - <div>Restored: <span x-text="$store.backupStore.restoreResult?.restored_files?.length || 0"></span></div>
233 - <div>Skipped: <span x-text="$store.backupStore.restoreResult?.skipped_files?.length || 0"></span></div>
234 - <div>Errors: <span x-text="$store.backupStore.restoreResult?.errors?.length || 0"></span></div>
235 - </div>
236 - </div>
237 -
238 - </div>
239 - </template>
240 - </div>
241 -
242 - <style>
243 - .upload-section {
244 - margin-bottom: 1.5rem;
245 - padding: 1rem;
246 - border: 2px dashed var(--c-border);
247 - border-radius: 4px;
248 - text-align: center;
249 - }
250 -
251 - .upload-label {
252 - display: block;
253 - margin-bottom: 0.5rem;
254 - font-weight: 600;
255 - }
256 -
257 - .restore-loading {
258 - width: 100%;
259 - text-align: center;
260 - margin-top: 2rem;
261 - margin-bottom: 2rem;
262 - color: var(--c-text-secondary);
263 - }
264 -
265 - #restore-metadata-editor {
266 - width: 100%;
267 - height: 25em;
268 - }
269 -
270 - .file-operations-container {
271 - margin-top: 0.5em;
272 - margin-bottom: 1em;
273 - }
274 -
275 - #restore-file-list {
276 - width: 100%;
277 - height: 15em;
278 - font-family: monospace;
279 - font-size: 0.85em;
280 - background: var(--c-bg-primary);
281 - color: var(--c-text-primary);
282 - border: 1px solid var(--c-border);
283 - border-radius: 4px;
284 - padding: 0.5em;
285 - resize: vertical;
286 - }
287 -
288 - .overwrite-policy {
289 - margin: 1rem 0;
290 - }
291 -
292 - .radio-option {
293 - display: block;
294 - margin: 0.5rem 0;
295 - }
296 -
297 - .radio-option input {
298 - margin-right: 0.5rem;
299 - }
300 -
301 - .restore-error {
302 - color: var(--c-error);
303 - margin: 0.5rem 0;
304 - padding: 0.5rem;
305 - background: var(--c-error-bg);
306 - border-radius: 4px;
307 - }
308 -
309 - .restore-result {
310 - margin: 1rem 0;
311 - padding: 1rem;
312 - background: var(--c-success-bg);
313 - border-radius: 4px;
314 - }
315 -
316 - .result-stats {
317 - display: flex;
318 - gap: 1rem;
319 - margin-top: 0.5rem;
320 - }
321 - </style>
322 -</body>
323 -</html>
324 -```
325 -
326 -### 5. Store Implementation
327 -
328 -#### File: `webui/components/settings/backup/backup-store.js`
329 -```javascript
330 -import { createStore } from "/js/AlpineStore.js";
331 -
332 -// ⚠️ CRITICAL: The .env file contains API keys and essential configuration.
333 -// This file is REQUIRED for Agent Zero to function and must be backed up.
334 -// Note: Patterns now use resolved absolute paths (e.g., /home/user/a0/data/.env)
335 -
336 -const model = {
337 - // State
338 - mode: 'backup', // 'backup' or 'restore'
339 - loading: false,
340 - loadingMessage: '',
341 - error: '',
342 -
343 - // File operations log (shared between backup and restore)
344 - fileOperationsLog: '',
345 -
346 - // Backup state
347 - backupMetadataConfig: null,
348 - includeHidden: false,
349 - previewStats: { total: 0, truncated: false },
350 - backupEditor: null,
351 -
352 - // Enhanced file preview state
353 - previewMode: 'grouped', // 'grouped' or 'flat'
354 - previewFiles: [],
355 - previewGroups: [],
356 - filteredPreviewFiles: [],
357 - fileSearchFilter: '',
358 - expandedGroups: new Set(),
359 -
360 - // Progress state
361 - progressData: null,
362 - progressEventSource: null,
363 -
364 - // Restore state
365 - backupFile: null,
366 - backupMetadata: null,
367 - restorePatterns: '',
368 - overwritePolicy: 'overwrite',
369 - restoreEditor: null,
370 - restoreResult: null,
371 -
372 - // Initialization
373 - async initBackup() {
374 - this.mode = 'backup';
375 - this.resetState();
376 - await this.initBackupEditor();
377 - await this.updatePreview();
378 - },
379 -
380 - async initRestore() {
381 - this.mode = 'restore';
382 - this.resetState();
383 - await this.initRestoreEditor();
384 - },
385 -
386 - resetState() {
387 - this.loading = false;
388 - this.error = '';
389 - this.backupFile = null;
390 - this.backupMetadata = null;
391 - this.restoreResult = null;
392 - this.fileOperationsLog = '';
393 - },
394 -
395 - // File operations logging
396 - addFileOperation(message) {
397 - const timestamp = new Date().toLocaleTimeString();
398 - this.fileOperationsLog += `[${timestamp}] ${message}\n`;
399 -
400 - // Auto-scroll to bottom
401 - this.$nextTick(() => {
402 - const textarea = document.getElementById(this.mode === 'backup' ? 'backup-file-list' : 'restore-file-list');
403 - if (textarea) {
404 - textarea.scrollTop = textarea.scrollHeight;
405 - }
406 - });
407 - },
408 -
409 - clearFileOperations() {
410 - this.fileOperationsLog = '';
411 - },
412 -
413 - // Cleanup method for modal close
414 - onClose() {
415 - this.resetState();
416 - if (this.backupEditor) {
417 - this.backupEditor.destroy();
418 - this.backupEditor = null;
419 - }
420 - if (this.restoreEditor) {
421 - this.restoreEditor.destroy();
422 - this.restoreEditor = null;
423 - }
424 - },
425 -
426 - // Get default backup metadata with resolved patterns from backend
427 - async getDefaultBackupMetadata() {
428 - const timestamp = new Date().toISOString();
429 -
430 - try {
431 - // Get resolved default patterns from backend
432 - const response = await sendJsonData("backup_get_defaults", {});
433 -
434 - if (response.success) {
435 - // Use patterns from backend with resolved absolute paths
436 - const include_patterns = response.default_patterns.include_patterns;
437 - const exclude_patterns = response.default_patterns.exclude_patterns;
438 -
439 - return {
440 - backup_name: `agent-zero-backup-${timestamp.slice(0, 10)}`,
441 - include_hidden: false,
442 - include_patterns: include_patterns,
443 - exclude_patterns: exclude_patterns,
444 - backup_config: {
445 - compression_level: 6,
446 - integrity_check: true
447 - }
448 - };
449 - }
450 - } catch (error) {
451 - console.warn("Failed to get default patterns from backend, using fallback");
452 - }
453 -
454 - // Fallback patterns (will be overridden by backend on first use)
455 - return {
456 - backup_name: `agent-zero-backup-${timestamp.slice(0, 10)}`,
457 - include_hidden: false,
458 - include_patterns: [
459 - // These will be replaced with resolved absolute paths by backend
460 - "# Loading default patterns from backend..."
461 - ],
462 - exclude_patterns: [],
463 - backup_config: {
464 - compression_level: 6,
465 - integrity_check: true
466 - }
467 - };
468 - },
469 -
470 - // Editor Management - Following Agent Zero ACE editor patterns
471 - async initBackupEditor() {
472 - const container = document.getElementById("backup-metadata-editor");
473 - if (container) {
474 - const editor = ace.edit("backup-metadata-editor");
475 -
476 - const dark = localStorage.getItem("darkMode");
477 - if (dark != "false") {
478 - editor.setTheme("ace/theme/github_dark");
479 - } else {
480 - editor.setTheme("ace/theme/tomorrow");
481 - }
482 -
483 - editor.session.setMode("ace/mode/json");
484 -
485 - // Initialize with default backup metadata
486 - const defaultMetadata = this.getDefaultBackupMetadata();
487 - editor.setValue(JSON.stringify(defaultMetadata, null, 2));
488 - editor.clearSelection();
489 -
490 - // Auto-update preview on changes (debounced)
491 - let timeout;
492 - editor.on('change', () => {
493 - clearTimeout(timeout);
494 - timeout = setTimeout(() => {
495 - this.updatePreview();
496 - }, 1000);
497 - });
498 -
499 - this.backupEditor = editor;
500 - }
501 - },
502 -
503 - async initRestoreEditor() {
504 - const container = document.getElementById("restore-metadata-editor");
505 - if (container) {
506 - const editor = ace.edit("restore-metadata-editor");
507 -
508 - const dark = localStorage.getItem("darkMode");
509 - if (dark != "false") {
510 - editor.setTheme("ace/theme/github_dark");
511 - } else {
512 - editor.setTheme("ace/theme/tomorrow");
513 - }
514 -
515 - editor.session.setMode("ace/mode/json");
516 - editor.setValue('{}');
517 - editor.clearSelection();
518 -
519 - // Auto-validate JSON on changes
520 - editor.on('change', () => {
521 - this.validateRestoreMetadata();
522 - });
523 -
524 - this.restoreEditor = editor;
525 - }
526 - },
527 -
528 - // ACE Editor utility methods - Following MCP servers pattern
529 - // Unified editor value getter (following MCP servers pattern)
530 - getEditorValue() {
531 - const editor = this.mode === 'backup' ? this.backupEditor : this.restoreEditor;
532 - return editor ? editor.getValue() : '{}';
533 - },
534 -
535 - // Unified JSON formatting (following MCP servers pattern)
536 - formatJson() {
537 - const editor = this.mode === 'backup' ? this.backupEditor : this.restoreEditor;
538 - if (!editor) return;
539 -
540 - try {
541 - const currentContent = editor.getValue();
542 - const parsed = JSON.parse(currentContent);
543 - const formatted = JSON.stringify(parsed, null, 2);
544 -
545 - editor.setValue(formatted);
546 - editor.clearSelection();
547 - editor.navigateFileStart();
548 - } catch (error) {
549 - console.error("Failed to format JSON:", error);
550 - this.error = "Invalid JSON: " + error.message;
551 - }
552 - },
553 -
554 - // Enhanced File Preview Operations
555 - async updatePreview() {
556 - try {
557 - const metadataText = this.getEditorValue();
558 - const metadata = JSON.parse(metadataText);
559 -
560 - if (!metadata.include_patterns || metadata.include_patterns.length === 0) {
561 - this.previewStats = { total: 0, truncated: false };
562 - this.previewFiles = [];
563 - this.previewGroups = [];
564 - return;
565 - }
566 -
567 - // Convert patterns arrays back to string format for API
568 - const patternsString = this.convertPatternsToString(metadata.include_patterns, metadata.exclude_patterns);
569 -
570 - // Get grouped preview for better UX
571 - const response = await sendJsonData("backup_preview_grouped", {
572 - patterns: patternsString,
573 - include_hidden: metadata.include_hidden || false,
574 - max_depth: 3,
575 - search_filter: this.fileSearchFilter
576 - });
577 -
578 - if (response.success) {
579 - this.previewGroups = response.groups;
580 - this.previewStats = response.stats;
581 -
582 - // Flatten groups for flat view
583 - this.previewFiles = [];
584 - response.groups.forEach(group => {
585 - this.previewFiles.push(...group.files);
586 - });
587 -
588 - this.applyFileSearch();
589 - } else {
590 - this.error = response.error;
591 - }
592 - } catch (error) {
593 - this.error = `Preview error: ${error.message}`;
594 - }
595 - },
596 -
597 - // Convert pattern arrays to string format for backend API
598 - convertPatternsToString(includePatterns, excludePatterns) {
599 - const patterns = [];
600 -
601 - // Add include patterns
602 - if (includePatterns) {
603 - patterns.push(...includePatterns);
604 - }
605 -
606 - // Add exclude patterns with '!' prefix
607 - if (excludePatterns) {
608 - excludePatterns.forEach(pattern => {
609 - patterns.push(`!${pattern}`);
610 - });
611 - }
612 -
613 - return patterns.join('\n');
614 - },
615 -
616 - // Validation for backup metadata
617 - validateBackupMetadata() {
618 - try {
619 - const metadataText = this.getEditorValue();
620 - const metadata = JSON.parse(metadataText);
621 -
622 - // Validate required fields
623 - if (!Array.isArray(metadata.include_patterns)) {
624 - throw new Error('include_patterns must be an array');
625 - }
626 - if (!Array.isArray(metadata.exclude_patterns)) {
627 - throw new Error('exclude_patterns must be an array');
628 - }
629 - if (!metadata.backup_name || typeof metadata.backup_name !== 'string') {
630 - throw new Error('backup_name must be a non-empty string');
631 - }
632 -
633 - this.backupMetadataConfig = metadata;
634 - this.error = '';
635 - return true;
636 - } catch (error) {
637 - this.error = `Invalid backup metadata: ${error.message}`;
638 - return false;
639 - }
640 - },
641 -
642 - // File Preview UI Management
643 - initFilePreview() {
644 - this.fileSearchFilter = '';
645 - this.expandedGroups.clear();
646 - this.previewMode = localStorage.getItem('backupPreviewMode') || 'grouped';
647 - },
648 -
649 - togglePreviewMode() {
650 - this.previewMode = this.previewMode === 'grouped' ? 'flat' : 'grouped';
651 - localStorage.setItem('backupPreviewMode', this.previewMode);
652 - },
653 -
654 - toggleGroup(groupPath) {
655 - if (this.expandedGroups.has(groupPath)) {
656 - this.expandedGroups.delete(groupPath);
657 - } else {
658 - this.expandedGroups.add(groupPath);
659 - }
660 - },
661 -
662 - isGroupExpanded(groupPath) {
663 - return this.expandedGroups.has(groupPath);
664 - },
665 -
666 - debounceFileSearch() {
667 - clearTimeout(this.searchTimeout);
668 - this.searchTimeout = setTimeout(() => {
669 - this.applyFileSearch();
670 - }, 300);
671 - },
672 -
673 - clearFileSearch() {
674 - this.fileSearchFilter = '';
675 - this.applyFileSearch();
676 - },
677 -
678 - applyFileSearch() {
679 - if (!this.fileSearchFilter.trim()) {
680 - this.filteredPreviewFiles = this.previewFiles;
681 - } else {
682 - const search = this.fileSearchFilter.toLowerCase();
683 - this.filteredPreviewFiles = this.previewFiles.filter(file =>
684 - file.path.toLowerCase().includes(search)
685 - );
686 - }
687 - },
688 -
689 - async exportFileList() {
690 - const fileList = this.previewFiles.map(f => f.path).join('\n');
691 - const blob = new Blob([fileList], { type: 'text/plain' });
692 - const url = URL.createObjectURL(blob);
693 - const a = document.createElement('a');
694 - a.href = url;
695 - a.download = 'backup-file-list.txt';
696 - a.click();
697 - URL.revokeObjectURL(url);
698 - },
699 -
700 - async copyFileListToClipboard() {
701 - const fileList = this.previewFiles.map(f => f.path).join('\n');
702 - try {
703 - await navigator.clipboard.writeText(fileList);
704 - toast('File list copied to clipboard', 'success');
705 - } catch (error) {
706 - toast('Failed to copy to clipboard', 'error');
707 - }
708 - },
709 -
710 - async showFilePreview() {
711 - // Validate backup metadata first
712 - if (!this.validateBackupMetadata()) {
713 - return;
714 - }
715 -
716 - try {
717 - this.loading = true;
718 - this.loadingMessage = 'Generating file preview...';
719 -
720 - const metadata = this.backupMetadataConfig;
721 - const patternsString = this.convertPatternsToString(metadata.include_patterns, metadata.exclude_patterns);
722 -
723 - const response = await sendJsonData("backup_test", {
724 - patterns: patternsString,
725 - include_hidden: metadata.include_hidden || false,
726 - max_files: 1000
727 - });
728 -
729 - if (response.success) {
730 - // Store preview data for file preview modal
731 - this.previewFiles = response.files;
732 - openModal('backup/file-preview.html');
733 - } else {
734 - this.error = response.error;
735 - }
736 - } catch (error) {
737 - this.error = `Preview error: ${error.message}`;
738 - } finally {
739 - this.loading = false;
740 - }
741 - },
742 -
743 - // Real-time Backup with Progress Streaming
744 - async createBackup() {
745 - // Validate backup metadata first
746 - if (!this.validateBackupMetadata()) {
747 - return;
748 - }
749 -
750 - try {
751 - this.loading = true;
752 - this.error = '';
753 - this.clearFileOperations();
754 - this.addFileOperation('Starting backup creation...');
755 -
756 - const metadata = this.backupMetadataConfig;
757 - const patternsString = this.convertPatternsToString(metadata.include_patterns, metadata.exclude_patterns);
758 -
759 - // Start real-time progress streaming
760 - const eventSource = new EventSource(`/backup_progress_stream?` + new URLSearchParams({
761 - patterns: patternsString,
762 - include_hidden: metadata.include_hidden || false,
763 - backup_name: metadata.backup_name
764 - }));
765 -
766 - this.progressEventSource = eventSource;
767 -
768 - eventSource.onmessage = (event) => {
769 - const data = JSON.parse(event.data);
770 -
771 - // Log file operations
772 - if (data.file_path) {
773 - this.addFileOperation(`Adding: ${data.file_path}`);
774 - } else if (data.message) {
775 - this.addFileOperation(data.message);
776 - }
777 -
778 - if (data.completed) {
779 - eventSource.close();
780 - this.progressEventSource = null;
781 -
782 - if (data.success) {
783 - this.addFileOperation(`Backup completed successfully: ${data.total_files} files, ${this.formatFileSize(data.backup_size)}`);
784 - // Download the completed backup
785 - this.downloadBackup(data.backup_path, metadata.backup_name);
786 - toast('Backup created successfully', 'success');
787 - } else if (data.error) {
788 - this.error = data.message || 'Backup creation failed';
789 - this.addFileOperation(`Error: ${this.error}`);
790 - }
791 -
792 - this.loading = false;
793 - } else {
794 - this.loadingMessage = data.message || 'Processing...';
795 - }
796 - };
797 -
798 - eventSource.onerror = (error) => {
799 - eventSource.close();
800 - this.progressEventSource = null;
801 - this.loading = false;
802 - this.error = 'Connection error during backup creation';
803 - this.addFileOperation(`Error: ${this.error}`);
804 - };
805 -
806 - } catch (error) {
807 - this.error = `Backup error: ${error.message}`;
808 - this.addFileOperation(`Error: ${error.message}`);
809 - this.loading = false;
810 - }
811 - },
812 -
813 - async downloadBackup(backupPath, backupName) {
814 - try {
815 - const response = await fetch('/backup_download', {
816 - method: 'POST',
817 - headers: { 'Content-Type': 'application/json' },
818 - body: JSON.stringify({ backup_path: backupPath })
819 - });
820 -
821 - if (response.ok) {
822 - const blob = await response.blob();
823 - const url = globalThis.URL.createObjectURL(blob);
824 - const a = document.createElement('a');
825 - a.href = url;
826 - a.download = `${backupName}.zip`;
827 - a.click();
828 - globalThis.URL.revokeObjectURL(url);
829 - }
830 - } catch (error) {
831 - console.error('Download error:', error);
832 - }
833 - },
834 -
835 - cancelBackup() {
836 - if (this.progressEventSource) {
837 - this.progressEventSource.close();
838 - this.progressEventSource = null;
839 - }
840 - this.loading = false;
841 - this.progressData = null;
842 - },
843 -
844 - resetToDefaults() {
845 - const defaultMetadata = this.getDefaultBackupMetadata();
846 - if (this.backupEditor) {
847 - this.backupEditor.setValue(JSON.stringify(defaultMetadata, null, 2));
848 - this.backupEditor.clearSelection();
849 - }
850 - this.updatePreview();
851 - },
852 -
853 - // Dry run functionality
854 - async dryRun() {
855 - if (this.mode === 'backup') {
856 - await this.dryRunBackup();
857 - } else if (this.mode === 'restore') {
858 - await this.dryRunRestore();
859 - }
860 - },
861 -
862 - async dryRunBackup() {
863 - // Validate backup metadata first
864 - if (!this.validateBackupMetadata()) {
865 - return;
866 - }
867 -
868 - try {
869 - this.loading = true;
870 - this.loadingMessage = 'Performing dry run...';
871 - this.clearFileOperations();
872 - this.addFileOperation('Starting backup dry run...');
873 -
874 - const metadata = this.backupMetadataConfig;
875 - const patternsString = this.convertPatternsToString(metadata.include_patterns, metadata.exclude_patterns);
876 -
877 - const response = await sendJsonData("backup_test", {
878 - patterns: patternsString,
879 - include_hidden: metadata.include_hidden || false,
880 - max_files: 10000
881 - });
882 -
883 - if (response.success) {
884 - this.addFileOperation(`Found ${response.files.length} files that would be backed up:`);
885 - response.files.forEach((file, index) => {
886 - this.addFileOperation(`${index + 1}. ${file.path} (${this.formatFileSize(file.size)})`);
887 - });
888 - this.addFileOperation(`\nTotal: ${response.files.length} files, ${this.formatFileSize(response.files.reduce((sum, f) => sum + f.size, 0))}`);
889 - this.addFileOperation('Dry run completed successfully.');
890 - } else {
891 - this.error = response.error;
892 - this.addFileOperation(`Error: ${response.error}`);
893 - }
894 - } catch (error) {
895 - this.error = `Dry run error: ${error.message}`;
896 - this.addFileOperation(`Error: ${error.message}`);
897 - } finally {
898 - this.loading = false;
899 - }
900 - },
901 -
902 - async dryRunRestore() {
903 - if (!this.backupFile) {
904 - this.error = 'Please select a backup file first';
905 - return;
906 - }
907 -
908 - try {
909 - this.loading = true;
910 - this.loadingMessage = 'Performing restore dry run...';
911 - this.clearFileOperations();
912 - this.addFileOperation('Starting restore dry run...');
913 -
914 - const formData = new FormData();
915 - formData.append('backup_file', this.backupFile);
916 - formData.append('restore_patterns', this.getEditorValue());
917 -
918 - const response = await fetch('/backup_restore_preview', {
919 - method: 'POST',
920 - body: formData
921 - });
922 -
923 - const result = await response.json();
924 -
925 - if (result.success) {
926 - this.addFileOperation(`Found ${result.files.length} files that would be restored:`);
927 - result.files.forEach((file, index) => {
928 - this.addFileOperation(`${index + 1}. ${file.path} -> ${file.target_path}`);
929 - });
930 - if (result.skipped_files && result.skipped_files.length > 0) {
931 - this.addFileOperation(`\nSkipped ${result.skipped_files.length} files:`);
932 - result.skipped_files.forEach((file, index) => {
933 - this.addFileOperation(`${index + 1}. ${file.path} (${file.reason})`);
934 - });
935 - }
936 - this.addFileOperation(`\nTotal: ${result.files.length} files to restore, ${result.skipped_files?.length || 0} skipped`);
937 - this.addFileOperation('Dry run completed successfully.');
938 - } else {
939 - this.error = result.error;
940 - this.addFileOperation(`Error: ${result.error}`);
941 - }
942 - } catch (error) {
943 - this.error = `Dry run error: ${error.message}`;
944 - this.addFileOperation(`Error: ${error.message}`);
945 - } finally {
946 - this.loading = false;
947 - }
948 - },
949 -
950 - // Enhanced Restore Operations with Metadata Display
951 - async handleFileUpload(event) {
952 - const file = event.target.files[0];
953 - if (!file) return;
954 -
955 - this.backupFile = file;
956 - this.error = '';
957 - this.restoreResult = null;
958 -
959 - try {
960 - this.loading = true;
961 - this.loadingMessage = 'Inspecting backup archive...';
962 -
963 - const formData = new FormData();
964 - formData.append('backup_file', file);
965 -
966 - const response = await fetch('/backup_inspect', {
967 - method: 'POST',
968 - body: formData
969 - });
970 -
971 - const result = await response.json();
972 -
973 - if (result.success) {
974 - this.backupMetadata = result.metadata;
975 -
976 - // Load complete metadata for JSON editing
977 - this.restoreMetadata = JSON.parse(JSON.stringify(result.metadata)); // Deep copy
978 -
979 - // Initialize restore editor with complete metadata JSON
980 - if (this.restoreEditor) {
981 - this.restoreEditor.setValue(JSON.stringify(this.restoreMetadata, null, 2));
982 - this.restoreEditor.clearSelection();
983 - }
984 -
985 - // Validate backup compatibility
986 - this.validateBackupCompatibility();
987 - } else {
988 - this.error = result.error;
989 - this.backupMetadata = null;
990 - }
991 - } catch (error) {
992 - this.error = `Inspection error: ${error.message}`;
993 - this.backupMetadata = null;
994 - } finally {
995 - this.loading = false;
996 - }
997 - },
998 -
999 - validateBackupCompatibility() {
1000 - if (!this.backupMetadata) return;
1001 -
1002 - const warnings = [];
1003 -
1004 - // Check Agent Zero version compatibility
1005 - // Note: Both backup and current versions are obtained via git.get_git_info()
1006 - const backupVersion = this.backupMetadata.agent_zero_version;
1007 - const currentVersion = "current"; // Retrieved from git.get_git_info() on backend
1008 -
1009 - if (backupVersion !== currentVersion && backupVersion !== "development") {
1010 - warnings.push(`Backup created with Agent Zero ${backupVersion}, current version is ${currentVersion}`);
1011 - }
1012 -
1013 - // Check backup age
1014 - const backupDate = new Date(this.backupMetadata.timestamp);
1015 - const daysSinceBackup = (Date.now() - backupDate) / (1000 * 60 * 60 * 24);
1016 -
1017 - if (daysSinceBackup > 30) {
1018 - warnings.push(`Backup is ${Math.floor(daysSinceBackup)} days old`);
1019 - }
1020 -
1021 - // Check system compatibility
1022 - const systemInfo = this.backupMetadata.system_info;
1023 - if (systemInfo && systemInfo.system) {
1024 - // Could add platform-specific warnings here
1025 - }
1026 -
1027 - if (warnings.length > 0) {
1028 - toast(`Compatibility warnings: ${warnings.join(', ')}`, 'warning');
1029 - }
1030 - },
1031 -
1032 - async performRestore() {
1033 - if (!this.backupFile) {
1034 - this.error = 'Please select a backup file';
1035 - return;
1036 - }
1037 -
1038 - try {
1039 - this.loading = true;
1040 - this.loadingMessage = 'Restoring files...';
1041 - this.error = '';
1042 - this.clearFileOperations();
1043 - this.addFileOperation('Starting file restoration...');
1044 -
1045 - const formData = new FormData();
1046 - formData.append('backup_file', this.backupFile);
1047 - formData.append('restore_patterns', this.getEditorValue());
1048 - formData.append('overwrite_policy', this.overwritePolicy);
1049 -
1050 - const response = await fetch('/backup_restore', {
1051 - method: 'POST',
1052 - body: formData
1053 - });
1054 -
1055 - const result = await response.json();
1056 -
1057 - if (result.success) {
1058 - // Log restored files
1059 - this.addFileOperation(`Successfully restored ${result.restored_files.length} files:`);
1060 - result.restored_files.forEach((file, index) => {
1061 - this.addFileOperation(`${index + 1}. ${file.archive_path} -> ${file.target_path}`);
1062 - });
1063 -
1064 - // Log skipped files
1065 - if (result.skipped_files && result.skipped_files.length > 0) {
1066 - this.addFileOperation(`\nSkipped ${result.skipped_files.length} files:`);
1067 - result.skipped_files.forEach((file, index) => {
1068 - this.addFileOperation(`${index + 1}. ${file.path} (${file.reason})`);
1069 - });
1070 - }
1071 -
1072 - // Log errors
1073 - if (result.errors && result.errors.length > 0) {
1074 - this.addFileOperation(`\nErrors during restoration:`);
1075 - result.errors.forEach((error, index) => {
1076 - this.addFileOperation(`${index + 1}. ${error.path}: ${error.error}`);
1077 - });
1078 - }
1079 -
1080 - this.addFileOperation(`\nRestore completed: ${result.restored_files.length} restored, ${result.skipped_files?.length || 0} skipped, ${result.errors?.length || 0} errors`);
1081 - this.restoreResult = result;
1082 - toast('Restore completed successfully', 'success');
1083 - } else {
1084 - this.error = result.error;
1085 - this.addFileOperation(`Error: ${result.error}`);
1086 - }
1087 - } catch (error) {
1088 - this.error = `Restore error: ${error.message}`;
1089 - this.addFileOperation(`Error: ${error.message}`);
1090 - } finally {
1091 - this.loading = false;
1092 - }
1093 - },
1094 -
1095 - // JSON Metadata Utilities
1096 - validateRestoreMetadata() {
1097 - try {
1098 - const metadataText = this.getEditorValue();
1099 - const metadata = JSON.parse(metadataText);
1100 -
1101 - // Validate required fields
1102 - if (!Array.isArray(metadata.include_patterns)) {
1103 - throw new Error('include_patterns must be an array');
1104 - }
1105 - if (!Array.isArray(metadata.exclude_patterns)) {
1106 - throw new Error('exclude_patterns must be an array');
1107 - }
1108 -
1109 - this.restoreMetadata = metadata;
1110 - this.error = '';
1111 - return true;
1112 - } catch (error) {
1113 - this.error = `Invalid JSON metadata: ${error.message}`;
1114 - return false;
1115 - }
1116 - },
1117 -
1118 - getCurrentRestoreMetadata() {
1119 - if (this.validateRestoreMetadata()) {
1120 - return this.restoreMetadata;
1121 - }
1122 - return null;
1123 - },
1124 -
1125 - // Restore Operations - Metadata Control
1126 - resetToOriginalMetadata() {
1127 - if (this.backupMetadata) {
1128 - this.restoreMetadata = JSON.parse(JSON.stringify(this.backupMetadata)); // Deep copy
1129 -
1130 - if (this.restoreEditor) {
1131 - this.restoreEditor.setValue(JSON.stringify(this.restoreMetadata, null, 2));
1132 - this.restoreEditor.clearSelection();
1133 - }
1134 - }
1135 - },
1136 -
1137 - loadDefaultPatterns() {
1138 - if (this.backupMetadata && this.backupMetadata.backup_config?.default_patterns) {
1139 - // Parse default patterns and update current metadata
1140 - const defaultPatterns = this.backupMetadata.backup_config.default_patterns;
1141 - // This would need to be implemented based on how default patterns are structured
1142 - // For now, just reset to original metadata
1143 - this.resetToOriginalMetadata();
1144 - }
1145 - },
1146 -
1147 - async showRestorePreview() {
1148 - if (!this.backupFile || !this.restorePatterns.trim()) {
1149 - this.error = 'Please select a backup file and specify restore patterns';
1150 - return;
1151 - }
1152 -
1153 - try {
1154 - this.loading = true;
1155 - this.loadingMessage = 'Generating restore preview...';
1156 -
1157 - const formData = new FormData();
1158 - formData.append('backup_file', this.backupFile);
1159 - formData.append('restore_patterns', this.getEditorValue());
1160 -
1161 - const response = await fetch('/backup_restore_preview', {
1162 - method: 'POST',
1163 - body: formData
1164 - });
1165 -
1166 - const result = await response.json();
1167 -
1168 - if (result.success) {
1169 - this.previewFiles = result.files;
1170 - openModal('backup/file-preview.html');
1171 - } else {
1172 - this.error = result.error;
1173 - }
1174 - } catch (error) {
1175 - this.error = `Preview error: ${error.message}`;
1176 - } finally {
1177 - this.loading = false;
1178 - }
1179 - },
1180 -
1181 - // Utility
1182 - formatTimestamp(timestamp) {
1183 - if (!timestamp) return 'Unknown';
1184 - return new Date(timestamp).toLocaleString();
1185 - },
1186 -
1187 - formatFileSize(bytes) {
1188 - if (!bytes) return '0 B';
1189 - const sizes = ['B', 'KB', 'MB', 'GB'];
1190 - const i = Math.floor(Math.log(bytes) / Math.log(1024));
1191 - return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`;
1192 - },
1193 -
1194 - formatDate(dateString) {
1195 - if (!dateString) return 'Unknown';
1196 - return new Date(dateString).toLocaleDateString();
1197 - },
1198 -
1199 - // Enhanced Metadata Management
1200 - toggleMetadataView() {
1201 - this.showDetailedMetadata = !this.showDetailedMetadata;
1202 - localStorage.setItem('backupShowDetailedMetadata', this.showDetailedMetadata);
1203 - },
1204 -
1205 - async exportMetadata() {
1206 - if (!this.backupMetadata) return;
1207 -
1208 - const metadataJson = JSON.stringify(this.backupMetadata, null, 2);
1209 - const blob = new Blob([metadataJson], { type: 'application/json' });
1210 - const url = URL.createObjectURL(blob);
1211 - const a = document.createElement('a');
1212 - a.href = url;
1213 - a.download = 'backup-metadata.json';
1214 - a.click();
1215 - URL.revokeObjectURL(url);
1216 - },
1217 -
1218 - // Progress Log Management
1219 - initProgressLog() {
1220 - this.progressLog = [];
1221 - this.progressLogId = 0;
1222 - },
1223 -
1224 - addProgressLogEntry(message, type = 'info') {
1225 - if (!this.progressLog) this.progressLog = [];
1226 -
1227 - this.progressLog.push({
1228 - id: this.progressLogId++,
1229 - time: new Date().toLocaleTimeString(),
1230 - message: message,
1231 - type: type
1232 - });
1233 -
1234 - // Keep log size manageable
1235 - if (this.progressLog.length > 100) {
1236 - this.progressLog = this.progressLog.slice(-50);
1237 - }
1238 -
1239 - // Auto-scroll to bottom
1240 - this.$nextTick(() => {
1241 - const logElement = document.getElementById('backup-progress-log');
1242 - if (logElement) {
1243 - logElement.scrollTop = logElement.scrollHeight;
1244 - }
1245 - });
1246 - },
1247 -
1248 - clearProgressLog() {
1249 - this.progressLog = [];
1250 - },
1251 -
1252 - // Watch for progress data changes to update log
1253 - watchProgressData() {
1254 - this.$watch('progressData', (newData) => {
1255 - if (newData && newData.message) {
1256 - const type = newData.error ? 'error' : newData.warning ? 'warning' : newData.success ? 'success' : 'info';
1257 - this.addProgressLogEntry(newData.message, type);
1258 - }
1259 - });
1260 - }
1261 -};
1262 -
1263 -const store = createStore("backupStore", model);
1264 -export { store };
1265 -```
1266 -
1267 -### 6. Integration Requirements
1268 -
1269 -#### Settings Tab Integration
1270 -The backup functionality is integrated as a dedicated "backup" tab in the settings system, providing:
1271 -- **Dedicated Tab**: Clean separation from other settings categories
1272 -- **Easy Access**: Users can quickly find backup/restore functionality
1273 -- **Organized Interface**: Backup operations don't clutter developer or other tabs
1274 -
1275 -#### Settings Button Handler
1276 -Update settings field button handling to open backup/restore modals when respective buttons are clicked in the backup tab.
1277 -
1278 -**Integration with existing `handleFieldButton()` method:**
1279 -```javascript
1280 -// In webui/js/settings.js - add to existing handleFieldButton method
1281 -async handleFieldButton(field) {
1282 - console.log(`Button clicked: ${field.id}`);
1283 -
1284 - if (field.id === "mcp_servers_config") {
1285 - openModal("settings/mcp/client/mcp-servers.html");
1286 - } else if (field.id === "backup_create") {
1287 - openModal("settings/backup/backup.html");
1288 - } else if (field.id === "backup_restore") {
1289 - openModal("settings/backup/restore.html");
1290 - }
1291 -}
1292 -```
1293 -
1294 -#### Modal System Integration
1295 -Use existing `openModal()` and `closeModal()` functions from the global modal system (`webui/js/modals.js`).
1296 -
1297 -#### Toast Notifications
1298 -Use existing Agent Zero toast system for consistent user feedback:
1299 -```javascript
1300 -// Use established toast patterns
1301 -globalThis.toast("Backup created successfully", "success");
1302 -globalThis.toast("Restore completed", "success");
1303 -globalThis.toast("Error creating backup", "error");
1304 -```
1305 -
1306 -#### ACE Editor Integration
1307 -The backup system follows Agent Zero's established ACE editor patterns **exactly** as implemented in MCP servers:
1308 -
1309 -**Theme Detection (identical to MCP servers):**
1310 -```javascript
1311 -// Exact pattern from webui/components/settings/mcp/client/mcp-servers-store.js
1312 -const container = document.getElementById("backup-metadata-editor");
1313 -if (container) {
1314 - const editor = ace.edit("backup-metadata-editor");
1315 -
1316 - const dark = localStorage.getItem("darkMode");
1317 - if (dark != "false") {
1318 - editor.setTheme("ace/theme/github_dark");
1319 - } else {
1320 - editor.setTheme("ace/theme/tomorrow");
1321 - }
1322 -
1323 - editor.session.setMode("ace/mode/json");
1324 - editor.setValue(JSON.stringify(defaultMetadata, null, 2));
1325 - editor.clearSelection();
1326 - this.backupEditor = editor;
1327 -}
1328 -```
1329 -
1330 -**Cleanup Pattern (following MCP servers):**
1331 -```javascript
1332 -onClose() {
1333 - if (this.backupEditor) {
1334 - this.backupEditor.destroy();
1335 - this.backupEditor = null;
1336 - }
1337 - // Additional cleanup...
1338 -}
1339 -```
1340 -
1341 -#### API Integration Patterns
1342 -The backup system uses Agent Zero's existing API communication methods for consistency:
1343 -
1344 -**Standard API Calls (using global sendJsonData):**
1345 -```javascript
1346 -// Use existing global sendJsonData function (from webui/index.js)
1347 -const response = await sendJsonData("backup_test", {
1348 - patterns: patternsString,
1349 - include_hidden: metadata.include_hidden || false,
1350 - max_files: 1000
1351 -});
1352 -
1353 -// Error handling follows Agent Zero patterns
1354 -if (response.success) {
1355 - this.previewFiles = response.files;
1356 -} else {
1357 - this.error = response.error;
1358 -}
1359 -```
1360 -
1361 -**File Upload API Calls:**
1362 -```javascript
1363 -// For endpoints that handle file uploads (restore operations)
1364 -const formData = new FormData();
1365 -formData.append('backup_file', this.backupFile);
1366 -formData.append('restore_patterns', this.getEditorValue());
1367 -
1368 -const response = await fetch('/backup_restore', {
1369 - method: 'POST',
1370 - body: formData
1371 -});
1372 -
1373 -const result = await response.json();
1374 -```
1375 -
1376 -**Server-Sent Events (progress streaming):**
1377 -```javascript
1378 -// Real-time progress updates using EventSource
1379 -const eventSource = new EventSource('/backup_progress_stream?' + new URLSearchParams({
1380 - patterns: patternsString,
1381 - backup_name: metadata.backup_name
1382 -}));
1383 -
1384 -eventSource.onmessage = (event) => {
1385 - const data = JSON.parse(event.data);
1386 - this.loadingMessage = data.message;
1387 - // Handle progress updates...
1388 -};
1389 -```
1390 -
1391 -#### Utility Function Integration
1392 -The backup system can leverage existing Agent Zero utility functions for consistency:
1393 -
1394 -**File Size Formatting:**
1395 -```javascript
1396 -// Check if Agent Zero has existing file size utilities
1397 -// If not available, implement following Agent Zero's style patterns
1398 -formatFileSize(bytes) {
1399 - if (!bytes) return '0 B';
1400 - const sizes = ['B', 'KB', 'MB', 'GB'];
1401 - const i = Math.floor(Math.log(bytes) / Math.log(1024));
1402 - return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`;
1403 -}
1404 -```
1405 -
1406 -**Time Formatting (following existing patterns):**
1407 -```javascript
1408 -// Use existing localization helpers if available
1409 -formatTimestamp(timestamp) {
1410 - if (!timestamp) return 'Unknown';
1411 - return new Date(timestamp).toLocaleString();
1412 -}
1413 -```
1414 -
1415 -**Error Handling Integration:**
1416 -```javascript
1417 -// Use existing error handling patterns
1418 -try {
1419 - const result = await backupOperation();
1420 - globalThis.toast("Operation completed successfully", "success");
1421 -} catch (error) {
1422 - console.error('Backup error:', error);
1423 - globalThis.toast(`Error: ${error.message}`, "error");
1424 -}
1425 -```
1426 -
1427 -### 8. Styling Guidelines
1428 -
1429 -#### CSS Variables
1430 -Use existing CSS variables for consistent theming:
1431 -- `--c-bg-primary`, `--c-bg-secondary`
1432 -- `--c-text-primary`, `--c-text-secondary`
1433 -- `--c-border`, `--c-error`, `--c-success-bg`
1434 -
1435 -#### Responsive Design
1436 -Ensure modals work on mobile devices with appropriate responsive breakpoints.
1437 -
1438 -#### Accessibility
1439 -- Proper ARIA labels for form elements
1440 -- Keyboard navigation support
1441 -- Screen reader compatibility
1442 -
1443 -### 9. Error Handling
1444 -
1445 -#### User-Friendly Messages
1446 -- Clear error messages for common scenarios
1447 -- Loading states with descriptive messages
1448 -- Success feedback with action confirmation
1449 -
1450 -#### Validation
1451 -- Client-side validation for file types
1452 -- Pattern syntax validation
1453 -- File size limits
1454 -
1455 -## Comprehensive Enhancement Summary
1456 -
1457 -### Enhanced File Preview System
1458 -- **Smart Directory Grouping**: Files organized by directory structure with 3-level depth limitation
1459 -- **Dual View Modes**: Toggle between grouped directory view and flat file list
1460 -- **Real-time Search**: Debounced search filtering by file name or path fragments
1461 -- **Expandable Groups**: Collapsible directory groups with file count badges and size indicators
1462 -- **Performance Optimization**: Limited display (50 files per group) with "show more" indicators
1463 -- **Export Capabilities**: Export file lists to text files or copy to clipboard
1464 -
1465 -### Real-time Progress Visualization
1466 -- **Live Progress Streaming**: Server-Sent Events for real-time backup/restore progress updates
1467 -- **Multi-stage Progress Bar**: Visual progress indicator with percentage and stage information
1468 -- **File-by-file Display**: Current file being processed with count progress (X/Y files)
1469 -- **Live Progress Log**: Scrollable, auto-updating log with timestamped entries
1470 -- **Progress Control**: Cancel operation capability with cleanup handling
1471 -- **Status Categorization**: Color-coded progress entries (info, warning, error, success)
1472 -
1473 -### Comprehensive Metadata Display
1474 -- **Enhanced Backup Information**: Basic info grid with creation date, author, version, file count, size, and checksum
1475 -- **Expandable Detailed View**: Collapsible sections for system info, environment details, and backup configuration
1476 -- **System Information Display**: Platform, architecture, Python version, hostname from backup metadata
1477 -- **Environment Context**: User, timezone, runtime mode, working directory information
1478 -- **Compatibility Validation**: Automatic compatibility checking with warnings for version mismatches and old backups
1479 -- **Metadata Export**: Export complete metadata.json for external analysis
1480 -
1481 -### Consistent UI Standards
1482 -- **Standardized Scrollable Areas**: All file lists and progress logs use consistent max-height (350px) with scroll
1483 -- **Monospace Font Usage**: File paths displayed in monospace for improved readability
1484 -- **Responsive Design**: Mobile-friendly layouts with proper breakpoints
1485 -- **Theme Integration**: Full CSS variable support for dark/light mode compatibility
1486 -- **Loading States**: Comprehensive loading indicators with descriptive messages
1487 -
1488 -### Advanced User Experience Features
1489 -- **Search and Filter**: Real-time file filtering with search term highlighting
1490 -- **Pattern Control Buttons**: "Reset to Original", "Load Defaults", "Preview Files" for pattern management
1491 -- **File Selection Preview**: Comprehensive file preview before backup/restore operations
1492 -- **Progress Cancellation**: User-controlled operation cancellation with proper cleanup
1493 -- **Error Recovery**: Clear error messages with suggested fixes and recovery options
1494 -- **State Persistence**: Remember user preferences (view mode, expanded groups, etc.)
1495 -
1496 -### Alpine.js Architecture Enhancements
1497 -- **Enhanced Store Management**: Extended backup store with grouped preview, progress tracking, and metadata handling
1498 -- **Event-driven Updates**: Real-time UI updates via Server-Sent Events integration
1499 -- **State Synchronization**: Proper Alpine.js reactive state management for complex UI interactions
1500 -- **Memory Management**: Cleanup of event sources, intervals, and large data structures
1501 -- **Performance Optimization**: Debounced search, efficient list rendering, and scroll management
1502 -
1503 -### Integration Features
1504 -- **Settings Modal Integration**: Seamless integration with existing Agent Zero settings system
1505 -- **Toast Notifications**: Success/error feedback using existing notification system
1506 -- **Modal System**: Proper integration with Agent Zero's modal management
1507 -- **API Layer**: Consistent API communication patterns following Agent Zero conventions
1508 -- **Error Handling**: Unified error handling and user feedback mechanisms
1509 -
1510 -### Accessibility and Usability
1511 -- **Keyboard Navigation**: Full keyboard support for all interactive elements
1512 -- **Screen Reader Support**: Proper ARIA labels and semantic HTML structure
1513 -- **Copy-to-Clipboard**: Quick clipboard operations for file lists and metadata
1514 -- **Export Options**: Multiple export formats for file manifests and metadata
1515 -- **Visual Feedback**: Clear visual indicators for loading, success, error, and warning states
1516 -
1517 -## Enhanced Restore Workflow with Pattern Editing
1518 -
1519 -### Metadata-Driven Restore Process
1520 -1. **Upload Archive**: User uploads backup.zip file in restore modal
1521 -2. **Parse Metadata**: System extracts and loads complete metadata.json
1522 -3. **Display JSON**: Complete metadata.json shown in ACE JSON editor
1523 -4. **Direct Editing**: User can modify include_patterns, exclude_patterns, and other settings directly
1524 -5. **JSON Validation**: Real-time validation of JSON syntax and structure
1525 -6. **Preview Changes**: User can preview which files will be restored based on current metadata
1526 -7. **Execute Restore**: Files restored according to final metadata configuration
1527 -
1528 -### JSON Metadata Editing Benefits
1529 -- **Single Source of Truth**: metadata.json is the authoritative configuration
1530 -- **Direct Control**: Users edit the exact JSON that will be used for restore
1531 -- **Full Access**: Modify any metadata property, not just patterns
1532 -- **Real-time Validation**: JSON syntax and structure validation as you type
1533 -- **Transparency**: See exactly what configuration will be applied
1534 -
1535 -### Enhanced User Experience
1536 -- **Intelligent Defaults**: Complete metadata automatically loaded from backup
1537 -- **JSON Editor**: Professional ACE editor with syntax highlighting and validation
1538 -- **Real-time Preview**: See exactly which files will be restored before proceeding
1539 -- **Immediate Feedback**: JSON validation and error highlighting as you edit
1540 -
1541 -This enhanced frontend specification delivers a professional-grade user interface with sophisticated file management, real-time progress monitoring, and comprehensive metadata visualization, all organized within a dedicated backup tab for optimal user experience. The implementation maintains perfect integration with Agent Zero's existing UI architecture and follows established Alpine.js patterns.
1542 -
1543 -### Implementation Status: ✅ COMPLETED & PRODUCTION READY
1544 -
1545 -### **Final Implementation State (December 2024)**
1546 -
1547 -#### **✅ COMPLETED Components:**
1548 -
1549 -**1. Settings Integration** ✅
1550 -- **Backup Tab**: Dedicated "Backup & Restore" tab in settings interface
1551 -- **Button Handlers**: Integrated with existing `handleFieldButton()` method
1552 -- **Modal System**: Uses existing Agent Zero modal management
1553 -- **Toast Notifications**: Consistent error/success feedback
1554 -
1555 -**2. Alpine.js Components** ✅
1556 -- **Backup Modal**: `webui/components/settings/backup/backup.html`
1557 -- **Restore Modal**: `webui/components/settings/backup/restore.html`
1558 -- **Backup Store**: `webui/components/settings/backup/backup-store.js`
1559 -- **Theme Integration**: Full dark/light mode support with CSS variables
1560 -
1561 -**3. Core Functionality** ✅
1562 -- **JSON Metadata Editing**: ACE editor with syntax highlighting and validation
1563 -- **File Preview**: Grouped directory view with search and filtering
1564 -- **Real-time Operations**: Live backup creation and restore progress
1565 -- **Error Handling**: Comprehensive validation and user feedback
1566 -- **Progress Monitoring**: File-by-file progress tracking and logging
1567 -
1568 -**4. User Experience Features** ✅
1569 -- **Drag & Drop**: File upload for restore operations
1570 -- **Search & Filter**: Real-time file filtering by name/path
1571 -- **Export Options**: File lists and metadata export
1572 -- **State Persistence**: Remember user preferences and expanded groups
1573 -- **Responsive Design**: Mobile-friendly layouts with proper breakpoints
1574 -
1575 -#### **✅ Backend Integration:**
1576 -
1577 -**API Endpoints Used:**
1578 -1. **`/backup_get_defaults`** - Get default patterns with resolved absolute paths
1579 -2. **`/backup_test`** - Pattern testing and dry run functionality
1580 -3. **`/backup_preview_grouped`** - Smart file grouping for UI display
1581 -4. **`/backup_create`** - Create and download backup archives
1582 -5. **`/backup_inspect`** - Extract metadata from uploaded archives
1583 -6. **`/backup_restore_preview`** - Preview restore operations
1584 -7. **`/backup_restore`** - Execute file restoration
1585 -
1586 -**Communication Patterns:**
1587 -- **Standard API**: Uses global `sendJsonData()` for consistency
1588 -- **File Upload**: FormData for archive uploads with proper validation
1589 -- **Error Handling**: Follows Agent Zero error formatting and toast patterns
1590 -- **Progress Updates**: Real-time file operation logging and status updates
1591 -
1592 -#### **✅ Key Technical Achievements:**
1593 -
1594 -**Enhanced Metadata Management:**
1595 -- **Direct JSON Editing**: Users edit metadata.json directly in ACE editor
1596 -- **Pattern Arrays**: Separate include_patterns/exclude_patterns for granular control
1597 -- **Real-time Validation**: JSON syntax checking and structure validation
1598 -- **System Information**: Complete backup context with platform/environment details
1599 -
1600 -**Advanced File Operations:**
1601 -- **Smart Grouping**: Directory-based organization with depth limitation
1602 -- **Hidden File Support**: Proper explicit vs wildcard pattern handling
1603 -- **Search & Filter**: Debounced search with real-time results
1604 -- **Export Capabilities**: File lists and metadata export functionality
1605 -
1606 -**Professional UI/UX:**
1607 -- **Consistent Styling**: Follows Agent Zero design patterns and CSS variables
1608 -- **Loading States**: Comprehensive progress indicators and status messages
1609 -- **Error Recovery**: Clear error messages with suggested fixes
1610 -- **Accessibility**: Keyboard navigation and screen reader support
1611 -
1612 -#### **✅ Frontend Architecture Benefits:**
1613 -
1614 -**Alpine.js Integration:**
1615 -- **Store Pattern**: Uses proven `createStore()` pattern from MCP servers
1616 -- **Component Lifecycle**: Proper initialization and cleanup following Agent Zero patterns
1617 -- **Reactive State**: Real-time UI updates with Alpine's reactivity system
1618 -- **Event Handling**: Leverages Alpine's declarative event system
1619 -
1620 -**Code Reuse:**
1621 -- **ACE Editor Setup**: Identical theme detection and configuration as MCP servers
1622 -- **Modal Management**: Uses existing Agent Zero modal and overlay systems
1623 -- **API Communication**: Consistent with Agent Zero's established API patterns
1624 -- **Error Handling**: Unified error formatting and toast notification system
1625 -
1626 -### **Implementation Quality Metrics:**
1627 -
1628 -**Code Quality:** ✅
1629 -- Follows Agent Zero coding conventions
1630 -- Proper error handling and validation
1631 -- Clean separation of concerns
1632 -- Comprehensive documentation
1633 -
1634 -**User Experience:** ✅
1635 -- Intuitive backup/restore workflow
1636 -- Real-time feedback and progress tracking
1637 -- Responsive design for all screen sizes
1638 -- Consistent with Agent Zero UI patterns
1639 -
1640 -**Performance:** ✅
1641 -- Efficient file preview with grouping
1642 -- Debounced search and filtering
1643 -- Proper memory management and cleanup
1644 -- Optimized for large file sets
1645 -
1646 -**Reliability:** ✅
1647 -- Comprehensive error handling
1648 -- Input validation and sanitization
1649 -- Proper file upload handling
1650 -- Graceful degradation for network issues
1651 -
1652 -### **Final Status: 🚀 PRODUCTION READY**
1653 -
1654 -The Agent Zero backup frontend is now:
1655 -- **Complete**: All planned features implemented and tested
1656 -- **Integrated**: Seamlessly integrated with existing Agent Zero infrastructure
1657 -- **Reliable**: Comprehensive error handling and edge case coverage
1658 -- **User-friendly**: Intuitive interface following Agent Zero design principles
1659 -- **Maintainable**: Clean code following established patterns and conventions
1660 -
1661 -**Ready for production use with full backup and restore capabilities!**
1662 -
1663 -The backup system provides users with a powerful, easy-to-use interface for backing up and restoring their Agent Zero configurations, data, and custom files using sophisticated pattern-based selection and real-time progress monitoring.
docs/getting-started/mcp-setup.md deleted
-178
@@ -1,178 +0,0 @@
1 -# Agent Zero: MCP Client Integration Guide
2 -
3 -This guide explains how to configure and utilize external tool providers through the Model Context Protocol (MCP) with Agent Zero. This allows Agent Zero to leverage tools hosted by separate local or remote MCP-compliant servers.
4 -
5 -> [!NOTE]
6 -> This guide covers Agent Zero as an MCP **client**. To expose Agent Zero as an MCP **server**, see [Connectivity → MCP Server](connectivity.md#mcp-server-connectivity).
7 -
8 -## What are MCP Servers?
9 -
10 -MCP servers are external processes or services that expose a set of tools that Agent Zero can use. Agent Zero acts as an MCP *client*, consuming tools made available by these servers. The integration supports three main types of MCP servers:
11 -
12 -1. **Local Stdio Servers**: These are typically local executables that Agent Zero communicates with via standard input/output (stdio).
13 -2. **Remote SSE Servers**: These are servers, often accessible over a network, that Agent Zero communicates with using Server-Sent Events (SSE), usually over HTTP/S.
14 -3. **Remote Streaming HTTP Servers**: These are servers that use the streamable HTTP transport protocol for MCP communication, providing an alternative to SSE for network-based MCP servers.
15 -
16 -## How Agent Zero Consumes MCP Tools
17 -
18 -Agent Zero discovers and integrates MCP tools dynamically:
19 -
20 -1. **Configuration**: You define the MCP servers Agent Zero should connect to in its configuration. The primary way to do this is through the Agent Zero settings UI.
21 -2. **Saving Settings**: When you save your settings via the UI, Agent Zero updates the `usr/settings.json` file, specifically the `"mcp_servers"` key.
22 -3. **Server Startup**: Agent Zero initializes configured MCP servers (stdio servers) or connects to them (remote servers). For `npx`/`uvx` based servers, the first run may download packages.
23 -4. **Tool Discovery**: Upon initialization (or when settings are updated), Agent Zero connects to each configured and enabled MCP server and queries it for the list of available tools, their descriptions, and expected parameters.
24 -5. **Dynamic Prompting**: The information about these discovered tools is then dynamically injected into the agent's system prompt. A placeholder like `{{tools}}` in a system prompt template (e.g., `prompts/agent.system.mcp_tools.md`) is replaced with a formatted list of all available MCP tools. This allows the agent's underlying Language Model (LLM) to know which external tools it can request.
25 -6. **Tool Invocation**: When the LLM decides to use an MCP tool, Agent Zero's `process_tools` method (handled by `mcp_handler.py`) identifies it as an MCP tool and routes the request to the appropriate `MCPConfig` helper, which then communicates with the designated MCP server to execute the tool.
26 -
27 -## Recommended MCP Servers
28 -Community-tested MCP servers include:
29 -
30 -- **Browser OS MCP** (browser automation)
31 -- **Chrome DevTools MCP** (browser automation)
32 -- **Playwright MCP** (browser automation)
33 -- **n8n MCP** (workflow automation)
34 -- **Gmail MCP** (email workflows)
35 -
36 -> [!TIP]
37 -> The built-in browser agent can be unreliable; MCP-based browser tools are the recommended alternative.
38 -
39 -## Docker Networking Notes
40 -If Agent Zero runs in Docker and your MCP server runs on the host:
41 -
42 -- Use `host.docker.internal` when available (macOS/Windows).
43 -- On Linux, run the MCP server in the same Docker network and reference it by container name.
44 -
45 -If your MCP server is remote, use its HTTPS URL in the configuration.
46 -
47 -## Configuration
48 -
49 -### Configuration File & Method
50 -
51 -The primary method for configuring MCP servers is through **Agent Zero's settings UI**.
52 -
53 -When you input and save your MCP server details in the UI, these settings are written to:
54 -
55 -* `usr/settings.json`
56 -
57 -### The `mcp_servers` Setting in `usr/settings.json`
58 -
59 -Within `usr/settings.json`, the MCP servers are defined under the `"mcp_servers"` key.
60 -
61 -* **Value Type**: The value for `"mcp_servers"` must be a **JSON formatted string**. The string itself contains either:
62 - * A JSON object containing `"mcpServers"` (recommended, matches the Settings UI)
63 - * A JSON array of server configuration objects
64 -* **Default Value**: An empty config (for example, `{"mcpServers": {}}`).
65 -* **Manual Editing (Advanced)**: While UI configuration is recommended, you can also manually edit `usr/settings.json`. If you do, ensure the `"mcp_servers"` value is a valid JSON string, with internal quotes properly escaped.
66 -
67 -**Example `mcp_servers` configuration (recommended format):**
68 -
69 -```json
70 -{
71 - "mcpServers": {
72 - "sqlite": {
73 - "command": "uvx",
74 - "args": ["mcp-server-sqlite", "--db-path", "/root/db.sqlite"]
75 - },
76 - "deep-wiki": {
77 - "description": "Use this MCP to analyze GitHub repositories",
78 - "url": "https://mcp.deepwiki.com/sse"
79 - }
80 - }
81 -}
82 -```
83 -*Note: In `usr/settings.json`, the entire value of `"mcp_servers"` is stored as a single string. The Settings UI handles escaping automatically.*
84 -
85 -* **Updating**: As mentioned, the recommended way to set or update this value is through Agent Zero's settings UI.
86 -* **For Existing `settings.json` Files (After an Upgrade)**: If you have an existing `usr/settings.json` from a version of Agent Zero prior to MCP server support, the `"mcp_servers"` key will likely be missing. To add this key:
87 - 1. Ensure you are running a version of Agent Zero that includes MCP server support.
88 - 2. Run Agent Zero and open its settings UI.
89 - 3. Save the settings (even without making changes). This action will write the complete current settings structure, including a default `"mcp_servers": ""` if not otherwise populated, to `usr/settings.json`. You can then configure your servers via the UI or by carefully editing this string.
90 -
91 -### MCP Server Configuration Structure
92 -
93 -Here are templates for configuring individual servers within the `mcp_servers` configuration:
94 -
95 -**1. Local Stdio Server**
96 -
97 -```json
98 -{
99 - "name": "My Local Tool Server",
100 - "description": "Optional: A brief description of this server.",
101 - "type": "stdio", // Optional: Explicitly specify server type. Can be "stdio", "sse", or streaming HTTP variants ("http-stream", "streaming-http", "streamable-http", "http-streaming"). Auto-detected if omitted.
102 - "command": "python", // The executable to run (e.g., python, /path/to/my_tool_server)
103 - "args": ["path/to/your/mcp_stdio_script.py", "--some-arg"], // List of arguments for the command
104 - "env": { // Optional: Environment variables for the command's process
105 - "PYTHONPATH": "/path/to/custom/libs:.",
106 - "ANOTHER_VAR": "value"
107 - },
108 - "encoding": "utf-8", // Optional: Encoding for stdio communication (default: "utf-8")
109 - "encoding_error_handler": "strict", // Optional: How to handle encoding errors. Can be "strict", "ignore", or "replace" (default: "strict").
110 - "disabled": false // Set to true to temporarily disable this server without removing its configuration.
111 -}
112 -```
113 -
114 -**2. Remote SSE Server**
115 -
116 -```json
117 -{
118 - "name": "My Remote API Tools",
119 - "description": "Optional: Description of the remote SSE server.",
120 - "type": "sse", // Optional: Explicitly specify server type. Can be "stdio", "sse", or streaming HTTP variants ("http-stream", "streaming-http", "streamable-http", "http-streaming"). Auto-detected if omitted.
121 - "url": "https://api.example.com/mcp-sse-endpoint", // The full URL for the SSE endpoint of the MCP server.
122 - "headers": { // Optional: Any HTTP headers required for the connection.
123 - "Authorization": "Bearer YOUR_API_KEY_OR_TOKEN",
124 - "X-Custom-Header": "some_value"
125 - },
126 - "timeout": 5.0, // Optional: Connection timeout in seconds (default: 5.0).
127 - "sse_read_timeout": 300.0, // Optional: Read timeout for the SSE stream in seconds (default: 300.0, i.e., 5 minutes).
128 - "disabled": false
129 -}
130 -```
131 -
132 -**3. Remote Streaming HTTP Server**
133 -
134 -```json
135 -{
136 - "name": "My Streaming HTTP Tools",
137 - "description": "Optional: Description of the remote streaming HTTP server.",
138 - "type": "streaming-http", // Optional: Explicitly specify server type. Can be "stdio", "sse", or streaming HTTP variants ("http-stream", "streaming-http", "streamable-http", "http-streaming"). Auto-detected if omitted.
139 - "url": "https://api.example.com/mcp-http-endpoint", // The full URL for the streaming HTTP endpoint of the MCP server.
140 - "headers": { // Optional: Any HTTP headers required for the connection.
141 - "Authorization": "Bearer YOUR_API_KEY_OR_TOKEN",
142 - "X-Custom-Header": "some_value"
143 - },
144 - "timeout": 5.0, // Optional: Connection timeout in seconds (default: 5.0).
145 - "sse_read_timeout": 300.0, // Optional: Read timeout for the SSE and streaming HTTP streams in seconds (default: 300.0, i.e., 5 minutes).
146 - "disabled": false
147 -}
148 -```
149 -
150 -**Example `mcp_servers` value in `usr/settings.json`:**
151 -
152 -```json
153 -{
154 - // ... other settings ...
155 - "mcp_servers": "[{'name': 'MyPythonTools', 'command': 'python3', 'args': ['mcp_scripts/my_server.py'], 'disabled': false}, {'name': 'ExternalAPI', 'url': 'https://data.example.com/mcp', 'headers': {'X-Auth-Token': 'supersecret'}, 'disabled': false}]",
156 - // ... other settings ...
157 -}
158 -```
159 -
160 -**Key Configuration Fields:**
161 -
162 -* `"name"`: A unique name for the server. This name will be used to prefix the tools provided by this server (e.g., `my_server_name.tool_name`). The name is normalized internally (converted to lowercase, spaces and hyphens replaced with underscores).
163 -* `"type"`: Optional explicit server type specification. Can be `"stdio"`, `"sse"`, or streaming HTTP variants (`"http-stream"`, `"streaming-http"`, `"streamable-http"`, `"http-streaming"`). If omitted, the type is auto-detected based on the presence of `"command"` (stdio) or `"url"` (defaults to sse for backward compatibility).
164 -* `"disabled"`: A boolean (`true` or `false`). If `true`, Agent Zero will ignore this server configuration.
165 -* `"url"`: **Required for Remote SSE and Streaming HTTP Servers.** The endpoint URL.
166 -* `"command"`: **Required for Local Stdio Servers.** The executable command.
167 -* `"args"`: Optional list of arguments for local Stdio servers.
168 -* Other fields are specific to the server type and mostly optional with defaults.
169 -
170 -## Using MCP Tools
171 -
172 -Once configured, successfully installed (if applicable, e.g., for `npx` based servers), and discovered by Agent Zero:
173 -
174 -* **Tool Naming**: MCP tools will appear to the agent with a name prefixed by the server name you defined (and normalized, e.g., lowercase, underscores for spaces/hyphens). For instance, if your server is named `"sequential-thinking"` in the configuration and it offers a tool named `"run_chain"`, the agent will know it as `sequential_thinking.run_chain`.
175 -* **Agent Interaction**: You can instruct the agent to use these tools. For example: "Agent, use the `sequential_thinking.run_chain` tool with the following input..." The agent's LLM will then formulate the appropriate JSON request.
176 -* **Execution Flow**: Agent Zero's `process_tools` method (with logic in `python/helpers/mcp_handler.py`) prioritizes looking up the tool name in the `MCPConfig`. If found, the execution is delegated to the corresponding MCP server. If not found as an MCP tool, it then attempts to find a local/built-in tool with that name.
177 -
178 -This setup provides a flexible way to extend Agent Zero's capabilities by integrating with various external tool providers without modifying its core codebase.
docs/guides/a2a-setup.md new
+153
@@ -0,0 +1,153 @@
1 +# A2A Server Setup
2 +
3 +Agent Zero can communicate with other Agent Zero instances using the A2A (Agent-to-Agent) protocol based on FastA2A. This guide shows you how to enable and configure A2A connectivity through the Settings UI.
4 +
5 +## What is A2A?
6 +
7 +A2A enables direct communication between multiple Agent Zero instances. This allows:
8 +
9 +- **Distributed workflows** - Delegate tasks to specialized agent instances
10 +- **Context isolation** - Maintain separate workspaces for different agents
11 +- **Long-running collaboration** - Persistent agent-to-agent conversations
12 +- **Project-specific delegation** - Route work to agents with specific project contexts
13 +
14 +> [!NOTE]
15 +> This guide covers enabling Agent Zero as an A2A server. For API-level integration details, see the [advanced connectivity documentation](../developer/connectivity.md).
16 +
17 +## Enabling the A2A Server
18 +
19 +### Step 1: Open A2A Configuration
20 +
21 +1. Click **Settings** in the sidebar
22 +2. Navigate to the **MCP/A2A** tab
23 +3. Scroll to the **A0 A2A Server** section
24 +4. Toggle **Enable A2A server** to ON
25 +
26 +![A2A Server Settings](../res/setup/a2a/a2a-conn.png)
27 +
28 +### Step 2: Get Connection URL
29 +
30 +1. Click on **connection example** to view your A2A connection details
31 +2. The dialog displays:
32 + - **API Token** - Automatically generated from your username and password
33 + - **A2A Connection URL** - The full URL other agents will use to connect
34 + - Optional **Project selector** - To create project-specific connection URLs
35 +
36 +![A2A Connection Dialog](../res/setup/a2a/a2a2.png)
37 +
38 +### Step 3: Save Configuration
39 +
40 +1. Click **Save** to apply your settings
41 +2. The A2A server is now active and ready to accept connections
42 +
43 +> [!IMPORTANT]
44 +> The API token changes when you update your Agent Zero credentials. Existing connections will need to be reconfigured with the new token.
45 +
46 +## Connection URL Format
47 +
48 +The basic A2A connection URL follows this format:
49 +
50 +```
51 +http://YOUR_HOST:PORT/a2a/t-YOUR_API_TOKEN
52 +```
53 +
54 +### With Project Context
55 +
56 +To connect with a specific project active:
57 +
58 +```
59 +http://YOUR_HOST:PORT/a2a/t-YOUR_API_TOKEN/p-PROJECT_NAME
60 +```
61 +
62 +When a project is specified:
63 +- All A2A conversations run in that project's context
64 +- The agent has access to project-specific resources and knowledge
65 +- Enables isolated, project-focused agent collaboration
66 +
67 +## Example Use Cases
68 +
69 +### 1. Local Development Setup
70 +
71 +Two Agent Zero instances on the same machine:
72 +
73 +```
74 +Instance 1: http://localhost:8080/a2a/t-abc123xyz
75 +Instance 2: http://localhost:8081/a2a/t-def456uvw
76 +```
77 +
78 +### 2. Remote Agent Collaboration
79 +
80 +Connect to a remote Agent Zero instance:
81 +
82 +```
83 +http://agent.example.com:8080/a2a/t-remote-token
84 +```
85 +
86 +### 3. Project-Specific Delegation
87 +
88 +Main agent delegates frontend work to specialized agent:
89 +
90 +```
91 +http://localhost:8081/a2a/t-frontend-token/p-webapp-ui
92 +```
93 +
94 +## Docker Networking
95 +
96 +If running Agent Zero in Docker:
97 +
98 +- **Same Host:** Use `host.docker.internal:PORT` (macOS/Windows) or container networking (Linux)
99 +- **Different Hosts:** Use the public IP or domain name of the target instance
100 +- **Port Mapping:** Ensure the Agent Zero port is exposed in your Docker configuration
101 +
102 +## Security Considerations
103 +
104 +- **Token Protection:** Keep your API tokens secure - they provide full access to your Agent Zero instance
105 +- **Network Access:** Consider using firewalls or reverse proxies to restrict A2A endpoint access
106 +- **HTTPS:** For production deployments, use HTTPS to encrypt A2A communication
107 +- **Credential Rotation:** Changing your password will invalidate all existing A2A connection URLs
108 +
109 +## Testing Your Connection
110 +
111 +You can test A2A connectivity using curl:
112 +
113 +```bash
114 +curl -X POST http://localhost:8080/a2a/t-YOUR_TOKEN \
115 + -H "Content-Type: application/json" \
116 + -d '{"message": "Hello from another agent"}'
117 +```
118 +
119 +## A2A vs MCP
120 +
121 +| Feature | A2A | MCP |
122 +|---------|-----|-----|
123 +| **Purpose** | Agent-to-agent chat delegation | Tool/function access |
124 +| **Use Case** | Long-running conversations | Specific tool calls |
125 +| **Context** | Full chat context | Function parameters only |
126 +| **Best For** | Workflow delegation | Tool integration |
127 +
128 +> [!TIP]
129 +> Use A2A when you need another agent's reasoning and conversation capabilities. Use MCP when you just need access to specific tools or functions.
130 +
131 +## Troubleshooting
132 +
133 +### Connection Refused
134 +
135 +- Verify the A2A server is enabled in Settings
136 +- Check that the Agent Zero instance is running
137 +- Confirm the port is accessible (check firewall rules)
138 +
139 +### Invalid Token
140 +
141 +- Token may have changed due to credential updates
142 +- Generate a new connection URL from Settings > MCP/A2A
143 +- Update the connecting agent's configuration
144 +
145 +### Project Not Found
146 +
147 +- Verify the project name in the URL matches exactly
148 +- Check that the project exists in the target instance
149 +- Project names are case-sensitive
150 +
151 +## Advanced Configuration
152 +
153 +For detailed A2A protocol specifications, API examples, and integration patterns, see the [Advanced Connectivity Guide](../developer/connectivity.md).
docs/guides/api-integration.md new
+231
@@ -0,0 +1,231 @@
1 +# Adding External APIs Without Code
2 +
3 +One of Agent Zero's most powerful capabilities is the ability to integrate external APIs on the fly without writing any code. By simply providing API documentation or code snippets, the agent can learn to use new services and remember how to use them in future conversations.
4 +
5 +This tutorial demonstrates how to integrate Google's image generation API from Google AI Studio - but the same process works for any public API.
6 +
7 +## How It Works
8 +
9 +Agent Zero can:
10 +
11 +1. **Analyze API code** - Understand how to use an API from provided snippets or documentation
12 +2. **Execute the integration** - Run the code to accomplish your task
13 +3. **Remember the solution** - Store the approach in its memory for future use
14 +4. **Manage credentials** - Use secrets stored globally or per-project for authentication
15 +
16 +This means you can add capabilities like image generation, translation services, payment processing, or any other API-based feature simply by showing the agent how it works once.
17 +
18 +## Example: Image Generation with Google AI Studio
19 +
20 +Let's walk through adding image generation capabilities using Google's Gemini API.
21 +
22 +### Step 1: Get the API Code
23 +
24 +First, we need the code snippet that shows how to use the API.
25 +
26 +1. Go to [Google AI Studio](https://aistudio.google.com/)
27 +2. Use the interface to create or test an image generation prompt
28 +3. Click **"Get Code"** in the UI
29 +4. Select **"Python"** as the language
30 +5. Download the code file (or copy it to clipboard)
31 +
32 +![Getting code from Google AI Studio](../res/usage/api-int/api-int-1.png)
33 +
34 +> [!TIP]
35 +> Most API platforms (OpenAI, Anthropic, Replicate, etc.) provide similar "Get Code" features or have documentation with ready-to-use snippets.
36 +
37 +### Step 2: Provide the Code to Agent Zero
38 +
39 +Now we'll tell Agent Zero to use this code:
40 +
41 +1. Open a chat with Agent Zero
42 +2. Send a message like: **"Use this code to generate an image of the Agent Zero logo"**
43 +3. Either:
44 + - Attach the downloaded Python file, or
45 + - Paste the code snippet into the chat
46 +
47 +Agent Zero will analyze the code and understand:
48 +- What dependencies are needed (`google-genai` package)
49 +- How to structure the API request
50 +- What parameters are required
51 +- How to handle the response
52 +
53 +![Agent Zero analyzing the API code](../res/usage/api-int/api-int-2image-gen-api2.png)
54 +
55 +### Step 3: Configure API Credentials
56 +
57 +On first run, Agent Zero will attempt to use the API but discover it needs an API key:
58 +
59 +![Missing API key error](../res/usage/api-int/api-int-3-api-key-missing-secrets.png)
60 +
61 +Agent Zero will tell you:
62 +- What credential is missing (e.g., `GEMINI_API_KEY`)
63 +- Where to configure it (Settings → External Services or Project settings)
64 +
65 +#### Adding the API Key
66 +
67 +You have two options for storing credentials:
68 +
69 +**Option 1: Global Secrets** (available to all chats and projects)
70 +1. Click the **Settings** icon in the sidebar
71 +2. Go to **External Services**
72 +3. Add a new line: `GEMINI_API_KEY=your_actual_key_here`
73 +4. Click **Save**
74 +
75 +**Option 2: Project Secrets** (available only within a specific project)
76 +1. Open your project settings
77 +2. Go to the **Secrets** tab
78 +3. Add the key-value pair
79 +4. Save the project
80 +
81 +![Configuring the API key in settings](../res/usage/api-int/api-int-4-secrets-setting.png)
82 +
83 +> [!NOTE]
84 +> Global secrets are ideal for APIs you use frequently across different projects. Project secrets are better for client-specific or project-specific integrations.
85 +
86 +### Step 4: Generate the Image
87 +
88 +After configuring the API key, tell Agent Zero to proceed:
89 +
90 +**"I set the API key in secrets. Now you can use it."**
91 +
92 +Agent Zero will:
93 +1. Retrieve the API key from secrets
94 +2. Install required dependencies (`google-genai` package)
95 +3. Execute the image generation code
96 +4. Save the generated image to disk
97 +5. Report the file location
98 +
99 +![Successful image generation](../res/usage/api-int/api-int-5-finish.png)
100 +
101 +The agent confirms:
102 +- Mission complete
103 +- File location: `/root/agent_zero_logo_0.jpg`
104 +- File size: 378 KB
105 +
106 +## How Memory Works
107 +
108 +Here's where it gets interesting: **Agent Zero will remember this solution**.
109 +
110 +The next time you ask it to generate an image:
111 +- It will automatically use the Gemini API approach it learned
112 +- No need to provide the code snippet again
113 +- The API key is already configured
114 +- Dependencies are already installed
115 +
116 +The agent stores:
117 +- **How to use the API** (code structure, parameters)
118 +- **What the API does** (image generation)
119 +- **What credentials are needed** (`GEMINI_API_KEY`)
120 +- **Common patterns and best practices** from the interaction
121 +
122 +This memory persists across:
123 +- Multiple conversations
124 +- Agent restarts
125 +- Different projects (for global memory and global secrets)
126 +
127 +## Use Cases
128 +
129 +This approach works for any external API. Common examples:
130 +
131 +### Communication & Notifications
132 +- **SendGrid**: Email delivery
133 +- **Twilio**: SMS and phone calls
134 +- **Slack/Discord**: Message webhooks
135 +- **Telegram**: Bot interactions
136 +
137 +### Data & Analytics
138 +- **Google Sheets API**: Spreadsheet automation
139 +- **Airtable**: Database operations
140 +- **Stripe**: Payment processing
141 +- **Plaid**: Banking data
142 +
143 +### Content & Media
144 +- **Unsplash/Pexels**: Stock photos
145 +- **ElevenLabs**: Text-to-speech
146 +- **Whisper API**: Speech-to-text
147 +- **Stable Diffusion**: Image generation
148 +- **Replicate**: Various AI models
149 +
150 +### Development Tools
151 +- **GitHub API**: Repository management
152 +- **Jira/Linear**: Issue tracking
153 +- **Vercel/Netlify**: Deployment
154 +- **Docker Hub**: Container registry
155 +
156 +### Specialized Services
157 +- **WeatherAPI**: Weather data
158 +- **Google Maps**: Geocoding, directions
159 +- **Currency exchange**: Forex rates
160 +- **Translation APIs**: Multi-language support
161 +
162 +## Best Practices
163 +
164 +### 1. Start with Official Examples
165 +
166 +Always use code snippets from official documentation or API providers' "Get Code" features. These are:
167 +- Tested and working
168 +- Up-to-date with latest API versions
169 +- Include proper error handling
170 +- Show recommended practices
171 +
172 +### 2. Organize Credentials
173 +
174 +**For personal/global APIs:**
175 +- Store in **Settings → External Services**
176 +- Use clear naming: `SERVICE_API_KEY`, `SERVICE_SECRET`
177 +- Add comments to document what each key is for
178 +
179 +**For project-specific APIs:**
180 +- Store in **Project Settings → Secrets**
181 +- Keeps client data isolated
182 +- Prevents accidental cross-project usage
183 +
184 +### 3. Document in Project Instructions
185 +
186 +When integrating APIs for a specific project, add notes to the project instructions:
187 +
188 +```markdown
189 +## Available APIs
190 +
191 +This project has access to:
192 +
193 +- **Gemini Image Generation**: Use for creating visuals and illustrations
194 + - Credentials: GEMINI_API_KEY (configured in project secrets)
195 + - Best for: Professional graphics, concept art, UI mockups
196 +
197 +- **SendGrid Email**: Use for sending automated emails
198 + - Credentials: SENDGRID_API_KEY
199 + - Best for: Notifications, reports, customer communications
200 +```
201 +
202 +This helps the agent understand what tools are available for the current project.
203 +
204 +## Advanced: Custom API Wrappers
205 +
206 +For APIs you use frequently, you can have Agent Zero create reusable wrapper functions:
207 +
208 +**"Create a Python module called `image_gen.py` with a function `generate_image(prompt, style='professional')` that uses the Gemini API. Include error handling and save the image to the current project folder."**
209 +
210 +Agent Zero will:
211 +1. Create a clean, reusable module
212 +2. Add proper documentation
213 +3. Include error handling
214 +4. Make it easy to call from future tasks
215 +
216 +Then in future chats:
217 +
218 +**"Use the image_gen module to create a logo"**, and it just works!
219 +
220 +## Conclusion
221 +
222 +By leveraging Agent Zero's ability to learn from API code snippets, you can:
223 +
224 +- **Add new capabilities instantly** without writing integration code
225 +- **Keep solutions in memory** for reuse across conversations
226 +- **Manage credentials securely** with global or project-scoped secrets
227 +- **Scale across any public API** using the same simple workflow
228 +
229 +This makes Agent Zero incredibly versatile - it's not limited to its built-in features. Show it how to use an API once, and it becomes part of its permanent toolkit.
230 +
231 +Ready to try it yourself? Pick any API you want to integrate and follow the steps above!
docs/guides/contribution.md renamed
+1 -1
@@ -5,7 +5,7 @@ Contributions to improve Agent Zero are very welcome! This guide outlines how t
5 ## Getting Started
6
7 - See [development](development.md) for instructions on how to set up a development environment.
8 -- See [extensibility](extensibility.md) for instructions on how to create custom extensions.
8 +- See [extensions](../developer/extensions.md) for instructions on how to create custom extensions.
9 - See [websocket infrastructure](websocket-infrastructure.md) for guidance on building real-time handlers and client integrations.
10
11 1. **Fork the Repository:** Fork the Agent Zero repository on GitHub.
docs/guides/mcp-setup.md new
+117
@@ -0,0 +1,117 @@
1 +# MCP Server Setup
2 +
3 +Agent Zero can connect to external MCP (Model Context Protocol) servers to extend its capabilities with additional tools. This guide shows you how to add MCP servers through the Settings UI.
4 +
5 +## What are MCP Servers?
6 +
7 +MCP servers are external tools that Agent Zero can use to perform specialized tasks. Popular examples include:
8 +
9 +- **Browser automation** (Chrome DevTools, Playwright)
10 +- **Workflow automation** (n8n)
11 +- **Email operations** (Gmail)
12 +- **Database access** (SQLite)
13 +
14 +> [!NOTE]
15 +> This guide covers connecting to external MCP servers as a client. For exposing Agent Zero as an MCP server, see the [advanced documentation](../developer/mcp-configuration.md).
16 +
17 +## Adding an MCP Server
18 +
19 +### Step 1: Open MCP Configuration
20 +
21 +1. Click **Settings** in the sidebar
22 +2. Navigate to the **MCP/A2A** tab
23 +3. Click on **External MCP Servers**
24 +4. Click the **Open** button to access the configuration editor
25 +
26 +![MCP Configuration Access](../res/setup/mcp/mcp-open-config.png)
27 +
28 +### Step 2: Add Your MCP Server
29 +
30 +In the JSON editor, add your MCP server configuration. Here's a simple example:
31 +
32 +```json
33 +{
34 + "mcpServers": {
35 + "chrome-devtools": {
36 + "command": "npx",
37 + "args": ["-y", "chrome-devtools-mcp@latest"]
38 + }
39 + }
40 +}
41 +```
42 +
43 +![MCP Configuration Example](../res/setup/mcp/mcp-example-config.png)
44 +
45 +### Step 3: Apply and Verify
46 +
47 +1. Click **Apply now** to save your configuration
48 +2. The server status will appear below, showing:
49 + - Server name (e.g., `chrome_devtools`)
50 + - Number of available tools
51 + - Connection status (green indicator = connected)
52 +
53 +> [!TIP]
54 +> The first time you run an `npx`-based MCP server, it may take a few moments to download and initialize.
55 +
56 +## Common MCP Server Examples
57 +
58 +### Local Command-Based Server
59 +
60 +```json
61 +{
62 + "mcpServers": {
63 + "sqlite": {
64 + "command": "uvx",
65 + "args": ["mcp-server-sqlite", "--db-path", "/root/db.sqlite"]
66 + }
67 + }
68 +}
69 +```
70 +
71 +### Remote HTTP Server
72 +
73 +```json
74 +{
75 + "mcpServers": {
76 + "external-api": {
77 + "url": "https://api.example.com/mcp",
78 + "headers": {
79 + "Authorization": "Bearer YOUR_API_KEY"
80 + }
81 + }
82 + }
83 +}
84 +```
85 +
86 +## Docker Networking
87 +
88 +If Agent Zero runs in Docker and your MCP server runs on the host:
89 +
90 +- **macOS/Windows:** Use `host.docker.internal` in URLs
91 +- **Linux:** Run the MCP server in the same Docker network and use the container name
92 +
93 +## Using MCP Tools
94 +
95 +Once connected, MCP tools become available to Agent Zero automatically. Tools are named with the server prefix, for example:
96 +
97 +- Server name: `chrome-devtools`
98 +- Tool becomes: `chrome_devtools.navigate_to_url`
99 +
100 +Simply ask Agent Zero to perform tasks, and it will use the appropriate MCP tools when needed.
101 +
102 +## Advanced Configuration
103 +
104 +For detailed configuration options, server types, environment variables, and troubleshooting, see the [Advanced MCP Configuration Guide](../developer/mcp-configuration.md).
105 +
106 +## Recommended MCP Servers
107 +
108 +Community-tested and reliable MCP servers:
109 +
110 +- **Chrome DevTools MCP** - Direct Chrome control
111 +- **Playwright MCP** - Cross-browser automation
112 +- **n8n MCP** - Workflow automation
113 +- **Gmail MCP** - Email management
114 +- **VSCode MCP** - IDE workflows
115 +
116 +> [!TIP]
117 +> For browser automation tasks, MCP-based browser tools are more reliable than the built-in browser agent.
docs/guides/projects.md new
+490
@@ -0,0 +1,490 @@
1 +# Working with Projects
2 +
3 +Projects are one of Agent Zero's most powerful features for organizing your work. They create isolated workspaces with dedicated context, instructions, memory, and secrets - preventing context bleed between unrelated tasks or clients.
4 +
5 +This tutorial will guide you through creating, configuring, and using projects effectively.
6 +
7 +## What Are Projects?
8 +
9 +A project in Agent Zero is an isolated workspace that includes:
10 +
11 +- **Dedicated folder structure** under `/a0/usr/projects/<project_name>/`
12 +- **Custom instructions** automatically injected into the agent's system prompt
13 +- **Isolated or shared memory** to prevent context pollution
14 +- **Project-specific secrets and variables** for secure credential management
15 +- **Custom agent configurations** including subagent settings
16 +- **Knowledge base integration** with project-scoped documents
17 +- **Git repository integration** for version-controlled codebases
18 +- **File structure injection** for automatic codebase awareness
19 +
20 +Think of projects as separate "personas" or "modes" for your agent - each with its own context, memory, and capabilities.
21 +
22 +## Creating Your First Project
23 +
24 +There are two ways to access the Projects interface:
25 +
26 +### Method 1: Dashboard Access
27 +1. Open the **Dashboard** from the sidebar
28 +2. Click the **Projects** button
29 +3. The Projects modal will open
30 +
31 +### Method 2: Quick Access
32 +1. Look at the top-right corner of the interface where it shows **"No project"**
33 +2. Click on it to open the project dropdown
34 +3. If you have no projects yet, click **"Projects"** to open the modal
35 +
36 +![Project Activation Dropdown](../res/usage/projects/projects-activate-project.png)
37 +
38 +### Creating an Empty Project
39 +
40 +Once in the Projects modal:
41 +
42 +1. Click **"Create project"** button
43 +2. You'll see the project creation wizard
44 +
45 +![Project Creation Form](../res/usage/projects/projects-creation.png)
46 +
47 +The wizard includes:
48 +
49 +- **Title**: A human-readable name displayed in the UI
50 +- **Color tag**: Visual identifier for quick recognition (choose from the color palette)
51 +- **Git Repository** (optional): URL to clone a repository (see next section)
52 +
53 +> [!TIP]
54 +> Choose meaningful titles and distinct colors, especially if you plan to work with multiple projects. This helps you quickly identify which project is active.
55 +
56 +### Creating a Git-Based Project
57 +
58 +Agent Zero's **Git Projects** feature allows you to clone repositories directly into your project workspace:
59 +
60 +1. In the creation form, enter a Git repository URL in the **Git Repository** field
61 + - Supports both public and private repositories
62 + - For private repositories, you can provide an authentication token
63 +2. Click **"Create and continue"**
64 +3. Agent Zero will clone the repository
65 +
66 +![Git Clone Progress](../res/usage/projects/projects-gitprojects-clone.png)
67 +
68 +The cloning process:
69 +- Downloads the repository to `/a0/usr/projects/<project_name>/`
70 +- By default, clones the `main` branch
71 +- Supports authentication via token (stored securely, never in URLs)
72 +- You can ask the agent to checkout different branches later
73 +
74 +![Git Project Status](../res/usage/projects/projects-git-projects-tree.png)
75 +
76 +After cloning completes, you'll see:
77 +- Repository URL
78 +- Current branch
79 +- Clean/dirty status
80 +- Last commit information
81 +
82 +> [!NOTE]
83 +> If the cloned repository already contains a `.a0proj/` folder with `project.json`, Agent Zero will merge the existing configuration with your specified title and color preferences.
84 +
85 +## Project Configuration
86 +
87 +Once created, you can configure your project through the Edit Project interface:
88 +
89 +![Project Description and Instructions](../res/usage/projects/projects-desc-and-instructions.png)
90 +
91 +### Description and Instructions
92 +
93 +#### Description
94 +The **Description** field helps both you and the agent understand the project's purpose. This is purely informational and helps provide context when switching between projects.
95 +
96 +**Example:**
97 +```
98 +An intelligent Excel automation system that processes financial spreadsheets
99 +from multiple sources, performs data validation and cleaning, consolidates
100 +information, generates executive reports, and flags anomalies or compliance issues.
101 +```
102 +
103 +#### Instructions
104 +The **Instructions** field is critical - these are automatically injected into the agent's system prompt when the project is active. Write clear, specific instructions that guide the agent's behavior for this project.
105 +
106 +**Example:**
107 +```markdown
108 +## Your Role
109 +You are an expert Financial Data Analyst and Excel Automation Specialist.
110 +Your job is to process, analyze, and report on financial spreadsheet data
111 +with precision and business acumen.
112 +
113 +## Operational Context
114 +- Work directory: `/usr/projects/excel-finance/`
115 +- Input data location: `/usr/projects/excel-finance/data/incoming/`
116 +- Processed files: `/usr/projects/excel-finance/data/processed/`
117 +- Reports output: `/usr/projects/excel-finance/reports/`
118 +- Templates: `/usr/projects/excel-finance/templates/`
119 +
120 +## Core Responsibilities
121 +
122 +### 1. Data Ingestion & Discovery
123 +- Scan `/data/incoming/` for new Excel/CSV files
124 +- Identify data types, sheets, and file structures
125 +- Log source details and timestamps
126 +
127 +### 2. Data Validation & Cleaning
128 +- Check for missing values, duplicates, and format inconsistencies
129 +- Validate numerical ranges and date formats
130 +- Flag suspicious patterns or outliers
131 +- Document all cleaning operations
132 +
133 +### 3. Data Consolidation
134 +- Merge data from multiple sources
135 +- Normalize column names and formats
136 +- Handle currency conversions and date standardization
137 +- Create master datasets for reporting
138 +
139 +### 4. Executive Reporting
140 +- Generate summary reports using templates in `/templates/`
141 +- Include key metrics, trends, and visualizations
142 +- Highlight anomalies and compliance issues
143 +- Export as formatted Excel files with proper styling
144 +
145 +### 5. Compliance & Quality Checks
146 +- Flag potential compliance issues
147 +- Verify calculations and formulas
148 +- Maintain audit trail of all operations
149 +- Alert on critical errors or anomalies
150 +
151 +## Quality Standards
152 +- Always validate input data before processing
153 +- Use professional Excel formatting in outputs
154 +- Include metadata (processing date, sources, versions)
155 +- Document assumptions and limitations
156 +- Provide clear error messages and suggestions
157 +```
158 +
159 +> [!IMPORTANT]
160 +> Well-written instructions are the key to effective project-specific agent behavior. Be specific about:
161 +> - The agent's role and expertise level
162 +> - Directory paths and file locations
163 +> - Expected workflows and procedures
164 +> - Quality standards and validation rules
165 +> - Output formats and requirements
166 +
167 +### Additional Instruction Files
168 +
169 +Besides the main instructions field, you can add multiple instruction files in the `.a0proj/instructions/` directory. These are automatically loaded and concatenated with the main instructions.
170 +
171 +This is useful for:
172 +- Organizing complex instructions into logical sections
173 +- Sharing common instructions across similar projects
174 +- Version controlling instruction updates via Git
175 +
176 +### Memory Isolation
177 +
178 +Projects support two memory modes:
179 +
180 +- **Own memory** (default): The project has its own isolated memory directory
181 + - Memories stored under `vector_db/projects/<project_name>/`
182 + - Prevents context bleed between projects
183 + - Ideal for client work, sensitive projects, or distinct domains
184 +
185 +- **Global memory**: The project shares the default memory pool
186 + - Memories stored under `vector_db/default/`
187 + - Useful when projects need shared knowledge
188 + - Better for related projects in the same domain
189 +
190 +> [!TIP]
191 +> Use **own memory** for:
192 +> - Client projects with confidential information
193 +> - Different programming languages/frameworks
194 +> - Distinct domains (e.g., finance vs. marketing)
195 +>
196 +> Use **global memory** for:
197 +> - Related sub-projects in the same domain
198 +> - When you want the agent to remember across all work
199 +> - Personal projects without sensitive data
200 +
201 +### Variables and Secrets
202 +
203 +Projects support scoped configuration values:
204 +
205 +#### Variables (Non-sensitive)
206 +Stored in `.a0proj/variables.env`:
207 +```bash
208 +API_BASE_URL=https://api.example.com
209 +DEFAULT_TIMEOUT=30
210 +OUTPUT_FORMAT=json
211 +LOG_LEVEL=info
212 +```
213 +
214 +#### Secrets (Sensitive)
215 +Stored in `.a0proj/secrets.env`:
216 +```bash
217 +API_KEY=sk-abc123xyz...
218 +DATABASE_PASSWORD=super_secret_pwd
219 +GITHUB_TOKEN=ghp_xyz789...
220 +SMTP_PASSWORD=email_pwd_here
221 +```
222 +
223 +> [!IMPORTANT]
224 +> - Secrets are stored locally in the container
225 +> - They are masked in the UI when editing
226 +> - Backups may not include secrets - keep a separate copy
227 +> - Reference secrets in prompts by name: "Use my `API_KEY` to authenticate"
228 +
229 +### Subagent Configuration
230 +
231 +Projects can enable or disable specific subagents (like the Browser Agent). This is configured via the UI and stored in `.a0proj/agents.json`.
232 +
233 +### Knowledge Files
234 +
235 +Import project-specific knowledge documents:
236 +1. Use the **Import Knowledge** button in the project interface
237 +2. Files are stored in `.a0proj/knowledge/` organized by memory area
238 +3. The agent can reference this knowledge when the project is active
239 +
240 +### File Structure Injection
241 +
242 +Projects can automatically inject their directory structure into the agent's context:
243 +
244 +**Settings (configurable per project):**
245 +- **Enabled**: Toggle automatic file tree injection
246 +- **Max depth**: How many directory levels to scan (default: 5)
247 +- **Max files**: Maximum files to include (default: 20)
248 +- **Max folders**: Maximum folders to include (default: 20)
249 +- **Max lines**: Maximum lines in the output (default: 250)
250 +- **Gitignore patterns**: Filter out unwanted files
251 +
252 +The default gitignore for projects excludes:
253 +```
254 +.a0proj/
255 +venv/
256 +__pycache__/
257 +node_modules/
258 +.npm/
259 +.git/
260 +```
261 +
262 +This feature is incredibly useful for code projects - the agent automatically "sees" your project structure and can navigate it intelligently.
263 +
264 +## Activating a Project
265 +
266 +To use a project, you need to activate it for your current chat:
267 +
268 +### In a New Chat
269 +1. Create or select a project from the Projects modal
270 +2. Start a new chat
271 +3. The project is automatically active for that chat
272 +
273 +### In an Existing Chat
274 +1. Click the project dropdown in the top-right corner (where it shows current project or "No project")
275 +2. Select the desired project from the list
276 +3. The project activates immediately for this chat
277 +
278 +![Project Activation](../res/usage/projects/projects-activate-project.png)
279 +
280 +> [!NOTE]
281 +> Each chat can have its own active project. You can have multiple chats open with different projects active simultaneously.
282 +
283 +### First Interaction After Activation
284 +
285 +Once activated, the agent's behavior changes according to the project's configuration:
286 +
287 +![First Operations in Project](../res/usage/projects/projects-first-ops.png)
288 +
289 +The agent now:
290 +- Has access to project-specific instructions
291 +- Uses project-isolated memory (if configured)
292 +- Can reference project secrets and variables
293 +- Sees the project file structure (if enabled)
294 +- Operates within the project's working directory
295 +
296 +**Example prompt after activation:**
297 +```
298 +Hi A0. Start first development phase:
299 +- recon
300 +- scope definition
301 +- AGENTS.md generation
302 +```
303 +
304 +The agent will understand the context based on the project's instructions and work accordingly.
305 +
306 +## Project Directory Structure
307 +
308 +Understanding the project directory structure helps you work effectively:
309 +
310 +```
311 +/a0/usr/projects/<project_name>/
312 +├── .a0proj/ # Project metadata (hidden)
313 +│ ├── project.json # Main configuration
314 +│ ├── variables.env # Non-sensitive variables
315 +│ ├── secrets.env # Sensitive credentials
316 +│ ├── agents.json # Subagent settings
317 +│ ├── instructions/ # Additional instruction files
318 +│ │ ├── 01-setup.md
319 +│ │ ├── 02-workflow.md
320 +│ │ └── ...
321 +│ └── knowledge/ # Project knowledge files
322 +│ ├── main/
323 +│ ├── fragments/
324 +│ └── ...
325 +├── src/ # Your actual project files
326 +├── data/ # Data files
327 +├── docs/ # Documentation
328 +└── ... # Other project content
329 +```
330 +
331 +> [!TIP]
332 +> The `.a0proj/` folder is automatically excluded from file structure injection (via gitignore patterns) to keep the agent's context clean.
333 +
334 +## Advanced Use Cases
335 +
336 +### Multi-Client Agency Work
337 +
338 +Use projects to isolate each client:
339 +
340 +```
341 +/usr/projects/client-acme/
342 +/usr/projects/client-globex/
343 +/usr/projects/client-initech/
344 +```
345 +
346 +Each with:
347 +- Client-specific instructions and context
348 +- Isolated memory (no data leakage)
349 +- Client API keys and credentials
350 +- Project-specific knowledge bases
351 +
352 +### Multi-Language Development
353 +
354 +Create projects for different tech stacks:
355 +
356 +```
357 +/usr/projects/python-ml-research/
358 +/usr/projects/nodejs-webapp/
359 +/usr/projects/go-microservices/
360 +```
361 +
362 +Each with language-specific:
363 +- Code patterns and best practices
364 +- Framework documentation
365 +- Linting and formatting rules
366 +
367 +### Domain-Specific Work
368 +
369 +Organize by business domain:
370 +
371 +```
372 +/usr/projects/finance-automation/
373 +/usr/projects/marketing-analytics/
374 +/usr/projects/hr-automation/
375 +```
376 +
377 +Each with domain-specific:
378 +- Terminology and concepts
379 +- Industry standards and regulations
380 +- Specialized tools and APIs
381 +
382 +## Combining Projects with Tasks
383 +
384 +Projects work exceptionally well with Agent Zero's **Tasks & Scheduling** feature:
385 +
386 +1. Create a project for a specific domain (e.g., "Daily Email Reports")
387 +2. Configure project instructions for the recurring task
388 +3. Schedule a task that activates this project
389 +4. The task runs in isolation with project-specific context
390 +
391 +**Example:**
392 +- **Project**: "Daily Sales Summary"
393 +- **Instructions**: "Fetch yesterday's sales data, generate summary report, email to team"
394 +- **Task**: Scheduled daily at 8 AM
395 +- **Result**: Consistent, context-aware automated reporting
396 +
397 +See [Tasks & Scheduling](usage.md#tasks--scheduling) for more details.
398 +
399 +## Best Practices
400 +
401 +### Instruction Writing
402 +- **Be specific**: Don't say "analyze data" - specify format, methods, and output
403 +- **Include paths**: Always mention where files should be read/written
404 +- **Define quality standards**: What constitutes "good" output?
405 +- **Specify error handling**: How should the agent respond to issues?
406 +- **Use markdown formatting**: Clear sections and lists improve readability
407 +
408 +### Memory Management
409 +- Use **own memory** by default for client work
410 +- Use **global memory** only when projects truly need shared knowledge
411 +- Regularly review and clean project memory via the Memory Dashboard
412 +- Clear memory when archiving completed projects
413 +
414 +### Security
415 +- Never commit `.a0proj/secrets.env` to version control
416 +- Use project-scoped secrets instead of global secrets for sensitive work
417 +- Consider separate projects for different security levels
418 +- Backup secrets manually - they may not be included in automatic backups
419 +
420 +### Organization
421 +- Use clear, descriptive project names
422 +- Choose distinct colors for visual identification
423 +- Keep instructions updated as project scope evolves
424 +- Document any manual setup steps in project instructions
425 +
426 +### Performance
427 +- Adjust file structure injection limits based on project size
428 +- Use gitignore patterns to exclude large build artifacts
429 +- Consider disabling file structure injection for very large codebases
430 +- Monitor memory growth and clean periodically
431 +
432 +## Troubleshooting
433 +
434 +### Project Not Loading Instructions
435 +**Problem**: Agent doesn't seem to follow project instructions
436 +
437 +**Solutions**:
438 +- Verify project is actually activated (check top-right dropdown)
439 +- Check instructions are saved (edit project and verify content)
440 +- Look for syntax errors in instructions markdown
441 +- Try deactivating and reactivating the project
442 +
443 +### Memory Not Isolated
444 +**Problem**: Agent remembers things from other projects
445 +
446 +**Solutions**:
447 +- Check project memory setting is "own" not "global"
448 +- Deactivate and reactivate the project
449 +- Clear the project's memory directory via Memory Dashboard
450 +- Restart chat context if necessary
451 +
452 +### Git Clone Failures
453 +**Problem**: Repository won't clone
454 +
455 +**Solutions**:
456 +- Verify the Git URL is correct
457 +- For private repos, ensure you provided a valid token
458 +- Check network connectivity
459 +- Try cloning manually via terminal to diagnose issue
460 +- Look for error messages in console/logs
461 +
462 +### Secrets Not Available
463 +**Problem**: Agent can't access project secrets
464 +
465 +**Solutions**:
466 +- Verify secrets are saved in project settings
467 +- Check secret variable names match what you're referencing
468 +- Try referencing by exact name: "use my `API_KEY`"
469 +- Ensure project is activated for current chat
470 +
471 +### File Structure Not Showing
472 +**Problem**: Agent doesn't see project files
473 +
474 +**Solutions**:
475 +- Enable file structure injection in project settings
476 +- Increase max_files/max_folders limits
477 +- Check gitignore patterns aren't too restrictive
478 +- Verify files exist in project directory
479 +
480 +## Next Steps
481 +
482 +Now that you understand projects, explore:
483 +
484 +- [Tasks & Scheduling](usage.md#tasks--scheduling) - Automate project-based work
485 +- [Memory Management](usage.md#memory-management) - Maintain project knowledge
486 +- [Backup & Restore](usage.md#backup--restore) - Preserve project configurations
487 +- [Extensions](../developer/extensions.md) - Extend project capabilities
488 +
489 +> [!TIP]
490 +> Start with a simple project to learn the system, then gradually add complexity. Projects are most powerful when instructions are well-crafted and memory is properly managed.
docs/guides/troubleshooting.md
+5 -5
@@ -3,13 +3,13 @@ This page addresses frequently asked questions (FAQ) and provides troubleshootin
3
4 ## Frequently Asked Questions
5 **1. How do I ask Agent Zero to work directly on my files or dirs?**
6 -- Place the files/dirs in `/a0/work_dir`. Agent Zero will be able to perform tasks on them.
6 +- Place the files/dirs in `/a0/usr`. Agent Zero will be able to perform tasks on them.
7
8 **2. When I input something in the chat, nothing happens. What's wrong?**
9 - Check if you have set up API keys in the Settings page. If not, the application cannot call LLM providers.
10
11 **3. I get “Invalid model ID.” What does that mean?**
12 -- Verify the **provider** and **model naming**. For example, `openai/gpt-4.1` is correct for OpenRouter, but **incorrect** for the native OpenAI provider.
12 +- Verify the **provider** and **model naming**. For example, `openai/gpt-5.3` is correct for OpenRouter, but **incorrect** for the native OpenAI provider, which goes without prefix.
13
14 **4. Does ChatGPT Plus include API access?**
15 - No. ChatGPT Plus does not include API credits. You must provide an OpenAI API key in Settings.
@@ -27,7 +27,7 @@ Refer to the [Choosing your LLMs](installation.md#installing-and-using-ollama-lo
27 Use **Settings → Backup & Restore** and avoid mapping the entire `/a0` directory. See [How to update Agent Zero](installation.md#how-to-update-agent-zero).
28
29 **8. My browser agent fails or is unreliable. What now?**
30 -The built-in browser agent is currently unstable on some systems. Use MCP alternatives such as Browser OS, Chrome DevTools, or Playwright. See [MCP Setup](mcp_setup.md).
30 +The built-in browser agent is currently unstable on some systems. Use Skills or MCP alternatives such as Browser OS, Chrome DevTools, or Vercel's Agent Browser. See [MCP Setup](mcp-setup.md).
31
32 **9. My secrets disappeared after a backup restore.**
33 Secrets are stored in `/a0/usr/secrets.env` and are not always included in backup archives. Copy them manually.
@@ -36,7 +36,7 @@ Secrets are stored in `/a0/usr/secrets.env` and are not always included in backu
36 - Join the Agent Zero [Skool](https://www.skool.com/agent-zero) or [Discord](https://discord.gg/B8KZKNsPpj) community.
37
38 **11. How do I adjust API rate limits?**
39 -Use the model rate limit fields in Settings (Chat/Utility/Embedding model sections) to set request/input/output limits. These map to the model config limits (for example `limit_requests`, `limit_input`, `limit_output`).
39 +Use the model rate limit fields in Settings (Chat/Utility/Browser model sections) to set request/input/output limits. These map to the model config limits (for example `limit_requests`, `limit_input`, `limit_output`).
40
41 **12. My `code_execution_tool` doesn't work, what's wrong?**
42 - Ensure Docker is installed and running.
@@ -44,7 +44,7 @@ Use the model rate limit fields in Settings (Chat/Utility/Embedding model sectio
44 - Verify that the Docker image is updated.
45
46 **13. Can Agent Zero interact with external APIs or services (e.g., WhatsApp)?**
47 -Yes, by creating custom tools or using MCP servers. See [Extensibility](extensibility.md) and [MCP Setup](mcp_setup.md).
47 +Yes, by creating custom tools or using MCP servers. See [Extensions](../developer/extensions.md) and [MCP Setup](mcp-setup.md).
48
49 ## Troubleshooting
50
docs/guides/usage.md
+738 -44
@@ -1,30 +1,29 @@
1 # Usage Guide
2 This guide explores usage and configuration scenarios for Agent Zero. You can consider this as a reference post-installation guide.
3
4 -![Utility Message with Solutions](../res/memory-man.png)
4 +![Utility Message with Solutions](../res/usage/first-task.png)
5
6 ## Basic Operations
7 Agent Zero provides several basic operations through its interface:
8
9 ### Restart Framework
10 -The Restart button allows you to quickly restart the Agent Zero framework without using the terminal:
10 +The Restart button allows you to quickly restart the Agent Zero container without using the terminal:
11
12 -![Restart Framework](../res/ui-restarting.png)
12 +![Restart Framework](../res/usage/restart.png)
13
14 -* Click the "Restart" button in the sidebar
15 -* A blue notification will appear indicating "Restarting..."
16 -* Once complete, a green success message "Restarted" will be shown
17 -* The framework will reinitialize while maintaining your current chat history and context
14 +* Click the "Restart" button in the sidebar dropdown
15 +* A blue inline confirmation will appear indicating "Confirm"
16 +* Once confirmed, the framework will reinitialize and restart the container
17
18 > [!TIP]
19 > Use the Restart function when you want to:
20 > - Reset the framework if you encounter unexpected behavior
22 -> - Reinitialize the system when agents become unresponsive
21 +> - See changes applied to the framework code
22
23 ### Action Buttons
24 Located beneath the chat input box, Agent Zero provides a set of action buttons for enhanced control and visibility:
25
27 -![Action Buttons](../res/ui-actions.png)
26 +![Action Buttons](../res/usage/action-btns.png)
27 #### Chat Flow Control
28 * **Pause/Resume Agent:** Toggle button to pause and resume chat flow
29 - Click to pause ongoing agent operations
@@ -36,14 +35,17 @@ Located beneath the chat input box, Agent Zero provides a set of action buttons
35 - Supports `.txt`, `.pdf`, `.csv`, `.html`, `.json`, and `.md` formats
36 - Files are stored in `/a0/knowledge/custom/main`
37 - Success message confirms successful import
39 - - See [knowledge](../advanced/architecture.md#knowledge) for more details
38 + - See [knowledge](../developer/architecture.md#knowledge) for more details
39
40 ### File Browser: Manage files in the Agent Zero environment
41 +
42 +![File Browser](../res/usage/file-browser.png)
43 +
44 - Upload new files and folders
45 - Download files (click filename) or folders (as zip archives)
44 - - Delete files and folders
46 + - Rename and Delete files and folders
47 - Navigate directories using the "Up" button
46 - - Support for file renaming and search coming soon
48 + - Edit files in the File Editor
49 - See [File Browser](#file-browser) section for detailed features
50
51 #### Debugging and Monitoring
@@ -52,7 +54,7 @@ Located beneath the chat input box, Agent Zero provides a set of action buttons
54 - Shows current conversation context
55 - Displays active instructions and parameters
56
55 -![Context](../res/ui-context.png)
57 +![Context](../res/usage/ui-context1.png)
58
59 ### History:
60 Access the chat history in JSON format
@@ -60,14 +62,14 @@ Access the chat history in JSON format
62 - Useful for debugging and understanding agent behavior
63 - Files are stored under `/a0/usr/chats/` inside the container
64
63 -![History](../res/ui-history.png)
65 +![History](../res/usage/ui-history1.png)
66
67 * **Nudge:** Restart the agent's last process
68 - Useful when agents become unresponsive
69 - Retries the last operation
70 - Helps recover from stuck states
71
70 -![Nudge](../res/ui-nudge.png)
72 +![Nudge](../res/usage/nudge.png)
73
74 > [!TIP]
75 > Use the Context and History buttons to understand how the agent interprets your instructions and debug any unexpected behavior.
@@ -83,7 +85,7 @@ Agent Zero supports direct file attachments in the chat interface for seamless f
85 - Images show thumbnails when available
86 - Files are listed in the chat input area waiting to be sent
87
86 -![File Attachments](../res/ui-attachments.png)
88 +![File Attachments](../res/usage/attachments-1.png)
89
90 #### Working with Attached Files
91 * Files can be referenced directly in your messages
@@ -93,13 +95,13 @@ Agent Zero supports direct file attachments in the chat interface for seamless f
95 - Perform operations on multiple files simultaneously
96 - Confirm successful file operations with detailed responses
97
96 -![Working with Attachments](../res/ui-attachments-2.png)
98 +![Working with Attachments](../res/usage/attachments-2.png)
99
100 > [!TIP]
101 > When working with multiple files, you can attach them all at once and then give instructions about what to do with them. The agent will handle them as a batch while keeping you informed of the progress.
102
103 ## Tool Usage
102 -Agent Zero's power comes from its ability to use [tools](../advanced/architecture.md#tools). Here's how to leverage them effectively:
104 +Agent Zero's power comes from its ability to use [tools](../developer/architecture.md#tools). Here's how to leverage them effectively:
105
106 - **Understand Tools:** Agent Zero includes default tools like knowledge (powered by SearXNG), code execution, and communication. Understand the capabilities of these tools and how to invoke them.
107
@@ -110,7 +112,19 @@ The built-in browser agent currently has dependency issues on some systems. If w
112 - **Chrome DevTools MCP**
113 - **Playwright MCP**
114
113 -See [MCP Setup](../getting-started/mcp-setup.md) for configuration guidance and recommended servers.
115 +See [MCP Setup](mcp-setup.md) for configuration guidance and recommended servers.
116 +
117 +### Agent-to-Agent (A2A) Communication
118 +
119 +Agent Zero instances can communicate with each other using the A2A protocol. This enables:
120 +
121 +- **Task delegation** to specialized agent instances
122 +- **Distributed workflows** across multiple agents
123 +- **Project-specific collaboration** with isolated contexts
124 +
125 +To enable A2A connectivity, go to **Settings → MCP/A2A → A0 A2A Server** and toggle the server on. You'll receive a connection URL that other Agent Zero instances can use to communicate with your agent.
126 +
127 +See [A2A Setup](a2a-setup.md) for detailed configuration and use cases.
128
129 ## Example of Tools Usage: Web Search and Code Execution
130 Let's say you want Agent Zero to perform some financial analysis tasks. Here's a possible prompt:
@@ -134,37 +148,502 @@ One of Agent Zero's unique features is multi-agent cooperation.
148
149 * **Creating Sub-Agents:** Agents can create sub-agents to delegate sub-tasks. This helps manage complexity and distribute workload.
150 * **Communication:** Agents can communicate with each other, sharing information and coordinating actions. The system prompt and message history play a key role in guiding this communication.
137 -* **Hierarchy:** Agent Zero uses a [hierarchical structure](../advanced/architecture.md#agent-hierarchy-and-communication), with superior agents delegating tasks to subordinates. This allows for structured problem-solving and efficient resource allocation.
151 +* **Hierarchy:** Agent Zero uses a [hierarchical structure](../developer/architecture.md#agent-hierarchy-and-communication), with superior agents delegating tasks to subordinates. This allows for structured problem-solving and efficient resource allocation.
152
139 -![](../res/physics.png)
140 -![](../res/physics-2.png)
153 +![](../res/usage/multi-agent.png)
154
155 ## Projects
143 -Projects create isolated workspaces with their own context, instructions, memory, and secrets. This prevents context bleed between unrelated tasks or clients.
156 +Projects are isolated workspaces that provide dedicated context, instructions, memory, and secrets for specific tasks or clients. They are one of Agent Zero's most powerful organizational features, preventing context bleed and enabling focused, specialized agent behavior.
157 +
158 +### What Projects Provide
159 +
160 +Each project includes:
161 +
162 +- **Isolated workspace** under `/a0/usr/projects/<project_name>/`
163 +- **Custom instructions** automatically injected into system prompts
164 +- **Dedicated or shared memory** to control context isolation
165 +- **Project-scoped secrets and variables** for secure credential management
166 +- **Git repository integration** for cloning and working with codebases
167 +- **File structure injection** for automatic codebase awareness
168 +- **Custom agent configurations** including subagent settings
169 +- **Knowledge base integration** with project-specific documents
170 +
171 +### Creating Projects
172 +
173 +There are two ways to access project management:
174 +
175 +1. **Dashboard Access**: Click **Projects** in the sidebar to open the Projects modal
176 +2. **Quick Access**: Click the project dropdown in the top-right corner (shows "No project" when none is active)
177 +
178 +![Project Creation](../res/usage/projects/projects-creation.png)
179 +
180 +#### Empty Projects
181 +
182 +Create a new empty project workspace:
183 +1. Click **"Create project"**
184 +2. Enter a **title** (human-readable name)
185 +3. Choose a **color tag** for visual identification
186 +4. Click **"Create and continue"**
187 +
188 +#### Git-Based Projects
189 +
190 +Clone a repository directly into your project workspace:
191 +1. Enter a **Git repository URL** (public or private)
192 +2. Optionally provide an authentication token for private repos
193 +3. Agent Zero clones the repository and sets up the project structure
194 +
195 +![Git Clone Progress](../res/usage/projects/projects-gitprojects-clone.png)
196 +
197 +The system clones the `main` branch by default. You can ask the agent to checkout other branches later. After cloning, you'll see repository status including current branch, clean/dirty state, and last commit info.
198 +
199 +![Git Project Status](../res/usage/projects/projects-git-projects-tree.png)
200 +
201 +> [!NOTE]
202 +> If the cloned repository already contains a `.a0proj/` configuration folder, Agent Zero merges the existing configuration with your specified preferences.
203 +
204 +### Project Configuration
205 +
206 +![Project Configuration](../res/usage/projects/projects-desc-and-instructions.png)
207 +
208 +#### Description and Instructions
209 +
210 +- **Description**: Helps you and the agent understand the project's purpose and context
211 +- **Instructions**: Critical field that gets injected into the agent's system prompt when the project is active
212 +
213 +> [!IMPORTANT]
214 +> Well-written instructions are key to effective project-specific behavior. Be specific about:
215 +> - The agent's role and expertise for this project
216 +> - Directory paths and file locations
217 +> - Expected workflows and procedures
218 +> - Quality standards and validation rules
219 +> - Output formats and requirements
220 +
221 +**Example instructions:**
222 +```markdown
223 +## Your Role
224 +You are an expert Financial Data Analyst working with Excel automation.
225 +
226 +## Operational Context
227 +- Work directory: `/usr/projects/excel-finance/`
228 +- Input data: `/usr/projects/excel-finance/data/incoming/`
229 +- Reports output: `/usr/projects/excel-finance/reports/`
230 +
231 +## Core Responsibilities
232 +1. Scan for new Excel/CSV files in incoming directory
233 +2. Validate and clean data (check for missing values, duplicates)
234 +3. Consolidate data from multiple sources
235 +4. Generate executive reports with visualizations
236 +5. Flag compliance issues and anomalies
237 +```
238 +
239 +#### Memory Isolation
240 +
241 +Choose how project memory is managed:
242 +
243 +- **Own memory** (recommended): Project has isolated memory under `vector_db/projects/<project_name>/`
244 + - Prevents context bleed between projects
245 + - Ideal for client work, sensitive projects, or distinct domains
246 +
247 +- **Global memory**: Project shares the default memory pool
248 + - Useful when projects need shared knowledge
249 + - Better for closely related projects
250 +
251 +#### Variables and Secrets
252 +
253 +Projects support scoped configuration:
254 +
255 +- **Variables** (non-sensitive): Stored in `.a0proj/variables.env`
256 + ```bash
257 + API_BASE_URL=https://api.example.com
258 + OUTPUT_FORMAT=json
259 + ```
260 +
261 +- **Secrets** (sensitive): Stored in `.a0proj/secrets.env`
262 + ```bash
263 + API_KEY=sk-abc123xyz...
264 + DATABASE_PASSWORD=super_secret_pwd
265 + ```
266 +
267 +Reference these in your prompts: "Use my `API_KEY` to authenticate with the service"
268 +
269 +> [!WARNING]
270 +> Secrets may not be included in backup archives. Keep a separate manual copy of critical credentials.
271 +
272 +#### File Structure Injection
273
145 -- Project files live under `/a0/usr/projects/<project_name>/`
146 -- Project instructions are automatically injected from `.a0proj/instructions/`
147 -- Project memory and knowledge are stored separately from global memory
274 +Projects can automatically inject their directory structure into the agent's context. This is configurable per project:
275
149 -See [Projects in Extensibility](../development/extensibility.md#projects) for structure details and file locations.
276 +- **Max depth**: Directory levels to scan (default: 5)
277 +- **Max files/folders**: Limits for context size
278 +- **Gitignore patterns**: Filter out build artifacts, dependencies, etc.
279 +
280 +The default ignores: `.a0proj/`, `venv/`, `__pycache__/`, `node_modules/`, `.git/`
281 +
282 +This feature helps the agent understand your codebase structure without manual explanation.
283 +
284 +### Activating Projects
285 +
286 +To use a project, activate it for your current chat:
287 +
288 +1. Click the project dropdown in the top-right corner
289 +2. Select the desired project from the list
290 +3. The project activates immediately
291 +
292 +![Project Activation](../res/usage/projects/projects-activate-project.png)
293 +
294 +Each chat can have its own active project. Multiple chats can use different projects simultaneously.
295 +
296 +Once activated, the agent:
297 +- Follows project-specific instructions
298 +- Uses project memory (if isolated)
299 +- Has access to project secrets and variables
300 +- Sees the project file structure (if enabled)
301 +- Works in the project directory by default
302 +
303 +![First Operations](../res/usage/projects/projects-first-ops.png)
304 +
305 +### Project Directory Structure
306 +
307 +```
308 +/a0/usr/projects/<project_name>/
309 +├── .a0proj/ # Project metadata (managed by A0)
310 +│ ├── project.json # Main configuration
311 +│ ├── variables.env # Non-sensitive config
312 +│ ├── secrets.env # Sensitive credentials
313 +│ ├── agents.json # Subagent settings
314 +│ ├── instructions/ # Additional instruction files
315 +│ └── knowledge/ # Project knowledge base
316 +├── src/ # Your actual project files
317 +├── data/ # Data files
318 +└── ... # Other project content
319 +```
320 +
321 +### Common Use Cases
322 +
323 +**Multi-Client Work**: Create separate projects for each client with isolated memory and credentials
324 +
325 +**Multi-Language Development**: Organize by tech stack (Python ML, Node.js webapp, Go microservices)
326 +
327 +**Domain-Specific Tasks**: Separate projects for finance, marketing, HR with domain-specific instructions
328 +
329 +**Automated Workflows**: Combine with [Tasks & Scheduling](#tasks--scheduling) for recurring project-based work
330 +
331 +### Best Practices
332 +
333 +- Use **own memory** by default for client work to prevent context bleed
334 +- Write **specific instructions** - mention paths, formats, and quality standards
335 +- Choose **distinct colors** for easy visual identification when switching
336 +- Keep **secrets separate** from version control - backup manually
337 +- **Adjust file structure limits** based on project size
338 +- **Clean memory periodically** via Memory Dashboard for optimal performance
339 +
340 +> [!TIP]
341 +> For a comprehensive guide to creating and managing projects, including detailed examples and troubleshooting, see the [Projects Tutorial](projects.md).
342 +
343 +See also:
344 +- [Projects in Extensions](../developer/extensions.md#projects) - Technical structure details
345 +- [Tasks & Scheduling](#tasks--scheduling) - Automate project-based work
346 +- [Memory Management](#memory-management) - Maintain project knowledge
347
348 ## Tasks & Scheduling
152 -Tasks allow Agent Zero to spawn scheduled or on-demand work in separate contexts.
349 +Tasks enable Agent Zero to run automated or scheduled work in isolated contexts. They're perfect for recurring workflows, batch processing, or time-delayed operations that don't require immediate attention.
350 +
351 +### What Are Tasks?
352 +
353 +Tasks are autonomous work units that Agent Zero executes in dedicated or shared chat contexts. Each task includes:
354 +
355 +- **Prompt and Instructions**: What the agent should do
356 +- **Execution Schedule**: When to run (cron schedule, specific times, or manual)
357 +- **Project Association**: Optional project context with its instructions and secrets
358 +- **Dedicated Context**: Each task can maintain its own conversation history
359 +- **State Management**: Tracks idle, running, disabled, or error states
360 +- **Result Tracking**: Stores last run time and execution results
361 +
362 +### Task Types
363 +
364 +Agent Zero supports three types of tasks:
365 +
366 +#### Scheduled Tasks
367 +Run on a recurring schedule using cron syntax:
368 +- **Daily reports**: `0 9 * * *` (every day at 9 AM)
369 +- **Hourly checks**: `0 * * * *` (every hour)
370 +- **Weekly summaries**: `0 9 * * 1` (Mondays at 9 AM)
371 +- **Custom intervals**: Full cron flexibility for complex schedules
372 +
373 +#### Planned Tasks
374 +Execute at specific, predetermined times:
375 +- **One-time future execution**: Single date/time
376 +- **Multi-step campaigns**: List of specific execution times
377 +- **Event-driven sequences**: Coordinate with external schedules
378 +
379 +#### Ad-hoc Tasks
380 +Manual execution for on-demand work:
381 +- **Quick batch jobs**: Run when needed
382 +- **Testing workflows**: Verify task configuration
383 +- **One-off operations**: Tasks that don't need scheduling
384 +
385 +### Creating Tasks
386 +
387 +#### From the UI
388 +
389 +Access the Task Scheduler from the sidebar:
390 +
391 +1. Click **Settings** → **Tasks Scheduler**
392 +2. Click **"New Task"** to create a task
393 +
394 +![Task Scheduler](../res/usage/tasks/scheduler-1.png)
395 +
396 +The scheduler shows:
397 +- **Task List**: All configured tasks with their state
398 +- **Filter Controls**: By type (scheduled, planned, ad-hoc) and state
399 +- **Quick Actions**: Run, pause, edit, or delete tasks
400 +- **Task Details**: Name, project association, last run, next run time
401 +
402 +#### From Chat
403 +
404 +Ask the agent to create tasks programmatically:
405 +
406 +```
407 +Create a scheduled task that checks my email inbox every morning at 8 AM
408 +and summarizes new messages from the last 24 hours.
409 +```
410 +
411 +The agent uses the `scheduler` tool to create tasks based on your natural language description.
412 +
413 +### Task Configuration
414
154 -- **Schedule from UI:** Settings → Tasks Scheduler can run a task at a specified time.
155 -- **Schedule from chat:** ask the agent to create a task for a future time.
156 -- **Dedicated context:** each task runs in its own chat context, which pairs well with Projects.
415 +![Edit Task](../res/usage/tasks/edit-task.png)
416 +
417 +When editing a task, you configure:
418 +
419 +#### Task Name
420 +A unique identifier for the task:
421 +- Use descriptive names: "Morning report for incoming Gmail"
422 +- Keep it concise but clear
423 +- Helps identify tasks in logs and notifications
424 +
425 +#### Task Type
426 +Choose the execution model:
427 +- **Scheduled**: Recurring cron-based execution
428 +- **Planned**: Specific date/time list
429 +- **Ad-hoc**: Manual execution only
430 +
431 +> [!NOTE]
432 +> Task type cannot be changed after creation. To switch types, create a new task.
433 +
434 +#### Project Association
435 +Optionally link the task to a project:
436 +
437 +**Benefits of project-scoped tasks:**
438 +- Task inherits project instructions automatically
439 +- Access to project-specific secrets and variables
440 +- Uses project's isolated memory (if configured)
441 +- Runs in project's working directory
442 +- Perfect for client-specific or domain-specific automation
443 +
444 +**Example:**
445 +- Project: "Financial Reports"
446 +- Task: "Daily Portfolio Summary"
447 +- Result: Task automatically uses financial analysis instructions, API keys, and memory from the project
448 +
449 +#### State Management
450 +Control task execution:
451 +
452 +- **Idle**: Ready to run when scheduled (green indicator)
453 +- **Running**: Currently executing (blue indicator)
454 +- **Disabled**: Won't execute even if scheduled (gray indicator)
455 +- **Error**: Last execution failed (red indicator)
456 +
457 +Toggle state to temporarily disable tasks without deleting them.
458 +
459 +#### Execution Plan
460 +For **Scheduled Tasks**, configure the cron schedule:
461 +
462 +**Common patterns:**
463 +```
464 +# Every day at 9 AM
465 +0 9 * * *
466 +
467 +# Every hour
468 +0 * * * *
469 +
470 +# Every Monday at 10 AM
471 +0 10 * * 1
472 +
473 +# Every 15 minutes
474 +*/15 * * * *
475 +
476 +# First day of month at midnight
477 +0 0 1 * *
478 +```
479 +
480 +**Timezone aware**: Tasks respect your configured timezone setting
481 +
482 +For **Planned Tasks**, add specific execution times:
483 +- Click "Add Execution Time"
484 +- Pick date and time
485 +- Tasks execute in order
486 +- Completed executions move to "Done" list
487 +
488 +### Task Execution
489 +
490 +#### Dedicated vs. Shared Context
491 +
492 +**Dedicated Context** (recommended):
493 +- Each task has its own isolated chat history
494 +- Prevents context pollution between tasks
495 +- Better for independent, recurring workflows
496 +- Default for UI-created tasks
497 +
498 +**Shared Context**:
499 +- Task shares a chat context (useful for agent-created tasks)
500 +- Can build on previous task executions
501 +- Useful for sequential, related operations
502 +
503 +#### Execution Flow
504 +
505 +When a task runs:
506 +
507 +1. **Context Preparation**
508 + - Creates or loads the task's chat context
509 + - Activates associated project (if configured)
510 + - Loads project instructions, secrets, and memory
511 +
512 +2. **Prompt Injection**
513 + - Injects system prompt (if specified)
514 + - Adds task-specific instructions
515 + - Includes any file attachments
516 +
517 +3. **Agent Execution**
518 + - Agent receives the prompt as a user message
519 + - Executes using available tools
520 + - Can use project-scoped resources
521 +
522 +4. **Result Handling**
523 + - Stores execution result and timestamp
524 + - Updates task state (idle or error)
525 + - Sends notifications (if configured)
526 + - For Planned Tasks: moves execution to "Done" list
527 +
528 +#### Monitoring Execution
529 +
530 +**Real-time monitoring:**
531 +- Running tasks show "Running" state in scheduler
532 +- View task's chat context to see agent progress
533 +- Stop tasks mid-execution if needed
534 +
535 +**Execution history:**
536 +- **Last Run**: Timestamp of most recent execution
537 +- **Next Run**: Scheduled time for next execution
538 +- **Last Result**: Output or error from last run
539 +
540 +### Common Use Cases
541 +
542 +#### Daily Reports
543 +```
544 +Task: "Morning Inbox Summary"
545 +Type: Scheduled (0 9 * * *)
546 +Project: "Email Automation"
547 +Prompt: "Check my Gmail inbox for new messages from the last 24 hours.
548 +Summarize important emails by category and highlight any urgent items."
549 +```
550 +
551 +#### Recurring Monitoring
552 +```
553 +Task: "Server Health Check"
554 +Type: Scheduled (*/30 * * * *)
555 +Project: "DevOps Monitoring"
556 +Prompt: "Check server status, CPU usage, and disk space.
557 +Alert me if any metric exceeds threshold."
558 +```
559 +
560 +#### Batch Processing
561 +```
562 +Task: "Weekly Data Export"
563 +Type: Scheduled (0 2 * * 0)
564 +Project: "Analytics"
565 +Prompt: "Export last week's analytics data to CSV.
566 +Upload to cloud storage and send summary report."
567 +```
568 +
569 +#### Campaign Automation
570 +```
571 +Task: "Product Launch Sequence"
572 +Type: Planned
573 +Executions:
574 + - 2026-03-01 09:00 - Send launch announcement
575 + - 2026-03-03 14:00 - Send feature highlights
576 + - 2026-03-07 10:00 - Send customer testimonials
577 +Project: "Marketing Campaigns"
578 +```
579 +
580 +### Integration with Projects
581 +
582 +Tasks and Projects are designed to work together:
583 +
584 +**Pattern: Project-Scoped Automation**
585 +
586 +1. Create a project with domain-specific instructions
587 + ```
588 + Project: "Customer Support"
589 + Instructions: "You are a customer support analyst.
590 + Monitor ticket queue, categorize by urgency, draft responses."
591 + ```
592 +
593 +2. Create a recurring task for that project
594 + ```
595 + Task: "Ticket Queue Monitor"
596 + Schedule: Every 2 hours
597 + Project: "Customer Support"
598 + Prompt: "Check new tickets and categorize them."
599 + ```
600 +
601 +3. Task automatically uses:
602 + - Project instructions (support analyst role)
603 + - Project secrets (support system API keys)
604 + - Project memory (previous ticket patterns)
605 + - Project file structure (template responses)
606 +
607 +**Benefits:**
608 +- Consistent behavior across task executions
609 +- No need to repeat instructions in each task
610 +- Easy to update behavior (edit project instructions once)
611 +- Clean separation of concerns (project = context, task = action)
612 +
613 +### Notifications
614 +
615 +Tasks can trigger notifications on completion or failure:
616 +
617 +- Configure notification preferences in Settings
618 +- Set up notification channels (email, Slack, webhook)
619 +- Tasks automatically send status updates
620 +- Critical for unattended automation
621 +
622 +See [Notifications](../developer/notifications.md) for configuration details.
623 +
624 +
625 +### Multi-Source Aggregation
626 +Tasks can pull from multiple sources:
627 +
628 +```
629 +"Aggregate data from:
630 +1. Sales CRM API
631 +2. Marketing analytics dashboard
632 +3. Customer support tickets
633 +Generate unified weekly report."
634 +```
635
636 > [!TIP]
159 -> Combine **Projects + Tasks + Notifications** for recurring, scoped workflows (e.g., daily inbox summaries). See [Notifications](../advanced/notifications.md) for alerts.
637 +> Combine **Projects + Tasks + Notifications** for powerful automation workflows. Example: Create a "Client Reports" project with instructions, then add scheduled tasks for each client that inherit those instructions automatically.
638
161 -## Prompt Engineering
162 -Effective prompt engineering is crucial for getting the most out of Agent Zero. Here are some tips and techniques:
639 +### Next Steps
640
164 -* **Be Clear and Specific:** Clearly state your desired outcome. The more specific you are, the better Agent Zero can understand and fulfill your request. Avoid vague or ambiguous language.
165 -* **Provide Context:** If necessary, provide background information or context to help the agent understand the task better. This might include relevant details, constraints, or desired format for the response.
166 -* **Break Down Complex Tasks:** For complex tasks, break them down into smaller, more manageable sub-tasks. This makes it easier for the agent to reason through the problem and generate a solution.
167 -* **Iterative Refinement:** Don't expect perfect results on the first try. Experiment with different prompts, refine your instructions based on the agent's responses, and iterate until you achieve the desired outcome. To achieve a full-stack, web-app development task, for example, you might need to iterate for a few hours for 100% success.
641 +Explore related features:
642 +
643 +- [Projects](#projects) - Create isolated contexts for tasks
644 +- [Notifications](../developer/notifications.md) - Understand A0's notification system
645 +- [Memory Management](#memory-management) - Understand task memory isolation
646 +- [Secrets & Variables](#secrets--variables) - Secure credentials for tasks
647
648 ## Secrets & Variables
649 Use the Settings → **Secrets** and **Variables** fields to store credentials and non-sensitive configuration values.
@@ -180,6 +659,71 @@ You can reference these values in prompts by name. For example, store `MY_GMAIL`
659 > [!NOTE]
660 > Project-scoped secrets and variables (when using Projects) live under `/a0/usr/projects/<project_name>/.a0proj/` (`secrets.env`, `variables.env`).
661
662 +## Remote Access via Tunneling
663 +
664 +Agent Zero includes a secure tunneling feature that allows you to expose your local instance to the internet. This makes it possible to access your Agent Zero instance from anywhere or share it with others without complex network configuration.
665 +
666 +### How Tunneling Works
667 +
668 +Agent Zero uses the [Flaredantic](https://pypi.org/project/flaredantic/) library to create secure tunnels. These tunnels:
669 +
670 +- Are secure (HTTPS)
671 +- Don't require any configuration
672 +- Generate unique URLs for each session
673 +- Can be regenerated on demand
674 +
675 +### Creating a Tunnel
676 +
677 +1. Open **Settings** in the sidebar
678 +2. Navigate to the **External Services** tab
679 +3. Click on **Flare Tunnel** in the navigation menu
680 +4. Click the **Create Tunnel** button to generate a new tunnel
681 +5. Once created, the tunnel URL will be displayed and can be copied to share with others
682 +6. The tunnel URL remains active until you stop the tunnel or close Agent Zero
683 +
684 +### Security Considerations
685 +
686 +When sharing your Agent Zero instance via a tunnel:
687 +
688 +- Anyone with the URL can access your Agent Zero instance
689 +- No additional authentication is added beyond what your Agent Zero instance already has
690 +- **Always set up authentication before creating a tunnel** (see below)
691 +- The tunnel exposes only your Agent Zero instance, not your entire system
692 +
693 +> [!IMPORTANT]
694 +> When attempting to create a tunnel without authentication configured, Agent Zero will display a security warning.
695 +
696 +### Adding Authentication for Tunnels
697 +
698 +To secure your tunneled Agent Zero instance, configure authentication in Settings:
699 +
700 +1. Open **Settings** in the Agent Zero UI
701 +2. Navigate to the **Authentication** section
702 +3. Enter your desired username in the **UI Login** field
703 +4. Enter a strong password in the **UI Password** field
704 +5. Click **Save** to apply the changes
705 +
706 +Alternatively, you can set environment variables:
707 +
708 +```bash
709 +AUTH_LOGIN=your_username
710 +AUTH_PASSWORD=your_password
711 +```
712 +
713 +This will require users to enter these credentials when accessing your tunneled Agent Zero instance.
714 +
715 +### Troubleshooting Tunnels
716 +
717 +If you encounter issues with the tunnel feature:
718 +
719 +1. Check your internet connection
720 +2. Try regenerating the tunnel URL
721 +3. Restart Agent Zero
722 +4. Check the console logs for any error messages
723 +
724 +> [!TIP]
725 +> Combine tunneling with authentication for secure remote access to your Agent Zero instance from any device, including mobile phones and tablets.
726 +
727 ## Voice Interface
728 Agent Zero provides both Text-to-Speech (TTS) and Speech-to-Text (STT) capabilities for natural voice interaction:
729
@@ -190,7 +734,7 @@ Enable voice responses from agents:
734 * Click the "Stop Speech" button above the input area to immediately stop any ongoing speech
735 * You can also click the speech button when hovering over messages to speak individual messages or their parts
736
193 -![TTS Stop Speech](../res/ui-tts-stop-speech.png)
737 +![TTS Stop Speech](../res/usage/ui-tts-stop-speech1.png)
738
739 - The interface allows users to stop speech at any time if a response is too lengthy or if they wish to intervene during the conversation.
740
@@ -225,7 +769,7 @@ Configure STT settings in the Settings page:
769 - Duration: Set how long silence should last before ending recording
770 - Timeout: Set maximum waiting time before closing the microphone
771
228 -![Speech to Text Settings](../res/ui-settings-5-speech-to-text.png)
772 +![Speech to Text Settings](../res/usage/ui-settings-5-speech-to-text.png)
773
774 > [!IMPORTANT]
775 > All STT and TTS functionalities operate locally within the Docker container,
@@ -240,7 +784,7 @@ Configure STT settings in the Settings page:
784 - Integrals, summations, and limits
785 - Mathematical alignments and equations
786
243 -![KaTeX display](../res/ui-katex-2.png)
787 +![KaTeX display](../res/usage/ui-katex-2.png)
788
789 > [!TIP]
790 > When asking the agent to solve mathematical problems, it will automatically respond using KaTeX formatting for clear and professional-looking mathematical expressions.
@@ -255,10 +799,11 @@ Agent Zero provides a powerful file browser interface for managing your workspac
799 - Size in bytes
800 - Last modified timestamp
801 - **Action Icons**: Each file/directory has:
802 + - menu for edit and rename actions
803 - Download button
804 - Delete button (with confirmation)
805
261 -![File Browser](../res/ui-file-browser.png)
806 +![File Browser](../res/usage/ui-file-browser.png)
807
808 #### Features
809 - **Directory Navigation**:
@@ -267,7 +812,7 @@ Agent Zero provides a powerful file browser interface for managing your workspac
812 - Current path always visible for context
813
814 > [!NOTE]
270 -> The file browser lets you navigate the Agent Zero filesystem. For file-based work, keep your working files in `/a0/work_dir` (or inside a Project workspace).
815 +> The file browser lets you navigate the Agent Zero filesystem. For file-based work, keep your working files in `/a0/usr` (or inside a Project workspace).
816 >
817 - **File Operations**:
818 - Create new files and directories
@@ -280,11 +825,160 @@ Agent Zero provides a powerful file browser interface for managing your workspac
825 - Last modification timestamps
826 - **Bulk Operations**:
827 - Upload multiple files simultaneously
283 - - Select and manage multiple files at once
828 +- **File and Directory Editing**:
829 + - Limited to 100MB files
830 + - Binary files cannot be edited
831
832 > [!TIP]
833 > The File Browser integrates seamlessly with Agent Zero's capabilities. You can reference files directly in your conversations, and the agent can help you manage, modify, and organize your files.
834
835 +## Memory Management
836 +Agent Zero includes a sophisticated memory management system that stores and retrieves information from conversations, knowledge sources, and learning experiences. The Memory Dashboard provides a powerful interface to view, search, filter, edit, and delete memory entries stored in the vector database.
837 +
838 +### Accessing the Memory Dashboard
839 +Open the Memory Dashboard from the sidebar to manage your agent's memory:
840 +
841 +1. Click the **Memory** button in the sidebar
842 +2. The dashboard displays all memory entries with their metadata and preview
843 +3. Memory entries are organized by directory (e.g., "default") and area (e.g., "All Areas", "main")
844 +
845 +![Memory Dashboard](../res/usage/memory-dashboard.png)
846 +
847 +### Dashboard Features
848 +
849 +#### Filtering and Organization
850 +The dashboard provides several ways to organize and filter memory entries:
851 +
852 +* **Memory Directory**: Select which memory directory to view (default or project-specific)
853 +* **Area Filter**: Filter memories by area to focus on specific contexts
854 +* **Limit Control**: Adjust the number of results displayed (default: 1000)
855 +* **Statistics Bar**: View counts at a glance:
856 + - Total: All memory entries in the directory
857 + - Filtered: Entries matching current filters
858 + - Knowledge: Entries from knowledge sources
859 + - Conversation: Entries from chat interactions
860 +
861 +#### Search Functionality
862 +Find specific memories using the powerful search feature:
863 +
864 +* **Search Bar**: Enter keywords to search memory content
865 +* **Threshold Slider**: Adjust search sensitivity (0.00 - 1.00)
866 + - Lower values return more results with looser matching
867 + - Higher values return fewer, more precise matches
868 + - Default threshold: 0.60
869 +* **Real-time Search**: Results update as you type
870 +
871 +> [!TIP]
872 +> Use the threshold slider to balance between broad discovery (lower values) and precise matching (higher values). Start with 0.60 and adjust based on your results.
873 +
874 +#### Memory Entry Information
875 +Each memory entry displays key information:
876 +
877 +* **Tags**: Visual indicators showing the memory type (MAIN, Knowledge, etc.)
878 +* **Timestamp**: When the memory was created (format: MM/DD HH:MM)
879 +* **Preview**: First few lines of the memory content
880 +* **Action Icons**: Quick access to view details, edit, or delete
881 +
882 +### Viewing and Editing Memories
883 +Click any memory entry to open the detailed view with full editing capabilities:
884 +
885 +![Memory Details](../res/usage/memory-editing.png)
886 +
887 +#### Memory Details View
888 +The details panel provides comprehensive information about each memory:
889 +
890 +* **Memory Content**: Full text of the stored memory
891 + - Syntax highlighting for structured content
892 + - Editable text area for modifications
893 +* **Metadata Panel**: Complete memory information
894 + - Unique ID
895 + - Area classification
896 + - Source type (e.g., "Knowledge")
897 + - Timestamp (creation date and time)
898 + - Source file (if applicable)
899 +
900 +#### Editing Memories
901 +Modify memory entries directly from the details view:
902 +
903 +1. Click on any memory entry to open the details panel
904 +2. Edit the memory content in the text area
905 +3. Click the **Save** button (checkmark icon) to apply changes
906 +4. Click the **Cancel** button (X icon) to discard changes
907 +
908 +> [!NOTE]
909 +> Edited memories are immediately updated in the vector database and will affect how the agent recalls and uses this information in future interactions.
910 +
911 +#### Deleting Memories
912 +Remove unwanted or outdated memory entries:
913 +
914 +1. Open the memory details view
915 +2. Click the **Delete** button (trash icon) in the action bar
916 +3. Confirm the deletion when prompted
917 +4. The memory is permanently removed from the vector database
918 +
919 +Alternatively, delete directly from the main dashboard:
920 +* Click the delete icon on any memory entry in the list
921 +* Confirm the deletion
922 +
923 +> [!WARNING]
924 +> Deleted memories cannot be recovered. Use caution when removing entries, especially those from knowledge sources or important conversations.
925 +
926 +#### Clearing Memories
927 +For bulk cleanup operations:
928 +
929 +* Click the **Clear** button in the dashboard header to remove all filtered memories
930 +* This is useful when you need to reset a specific area or start fresh with a memory directory
931 +* Always review your filters before clearing to avoid unintended deletions
932 +
933 +### Memory Types and Sources
934 +
935 +#### Knowledge Memories
936 +Memories derived from uploaded knowledge files:
937 +* Marked with "Knowledge" tag
938 +* Include source file information
939 +* Created when importing documents via Import Knowledge button
940 +* Stored persistently unless manually deleted
941 +
942 +#### Conversation Memories
943 +Memories from chat interactions:
944 +* Marked with conversation indicators
945 +* Created automatically as the agent learns from interactions
946 +* Include contextual information about when and why they were created
947 +* Help the agent maintain continuity across sessions
948 +
949 +### Best Practices with Memory
950 +
951 +#### Regular Maintenance
952 +* **Review Periodically**: Check your memory entries monthly to remove outdated information
953 +* **Organize by Area**: Use areas to categorize memories by project or topic
954 +* **Clean Up Test Data**: Remove experimental or test memories that aren't needed
955 +* **Monitor Growth**: Keep an eye on total memory count to maintain performance
956 +
957 +#### Search Optimization
958 +* **Use Specific Keywords**: More specific terms yield better results
959 +* **Adjust Threshold**: Fine-tune the threshold based on your needs
960 +* **Filter First**: Use area and directory filters before searching for better results
961 +* **Iterate Searches**: Try different search terms if initial results aren't helpful
962 +
963 +#### Content Quality
964 +* **Keep Relevant**: Remove memories that are no longer useful or accurate
965 +* **Update Information**: Edit memories when information becomes outdated
966 +* **Add Context**: When editing, ensure memories remain clear and useful
967 +* **Avoid Duplicates**: Remove redundant memories that store the same information
968 +
969 +#### Project Integration
970 +When using Projects (see [Projects](#projects)):
971 +* Each project maintains its own memory directory
972 +* Memories are isolated between projects to prevent context bleed
973 +* Use project-specific memory directories for focused work
974 +* Clear project memories when archiving completed projects
975 +
976 +> [!TIP]
977 +> Combine memory management with the backup system to preserve important memory states. Before clearing or making bulk changes, create a backup so you can restore if needed.
978 +
979 +> [!IMPORTANT]
980 +> Memory management directly affects agent behavior and recall. Regularly maintaining your memory database ensures optimal agent performance and relevant context retention.
981 +
982 ## Backup & Restore
983 Agent Zero provides a comprehensive backup and restore system to protect your data and configurations. This feature helps you safeguard your work and migrate Agent Zero setups between different systems.
984
docs/quickstart.md
+7 -3
@@ -12,7 +12,7 @@ Download and install Docker Desktop for your operating system:
12 - **Linux:** Install Docker Desktop or docker-ce following the [official instructions](https://docs.docker.com/desktop/install/linux-install/)
13
14 > [!TIP]
15 -> For complete OS-specific installation instructions, see the [full Installation Guide](getting-started/installation.md#step-1-install-docker-desktop).
15 +> For complete OS-specific installation instructions, see the [full Installation Guide](setup/installation.md#step-1-install-docker-desktop).
16
17 ### Step 2: Pull the Agent Zero Image
18
@@ -43,11 +43,11 @@ Open your browser and navigate to `http://localhost:<PORT>`. The Web UI will sho
43 Click **Add your API key** to open Settings and configure:
44
45 - **Default Provider:** OpenRouter (supports most models with a single API key)
46 -- **Alternative Providers:** Anthropic, OpenAI, Ollama (local models), and many others
46 +- **Alternative Providers:** Anthropic, OpenAI, Ollama/LM Studio (local models), and many others
47 - **Model Selection:** Choose your chat model (e.g., `anthropic/claude-sonnet-4-5` for OpenRouter)
48
49 > [!NOTE]
50 -> Agent Zero supports any LLM provider, including local models via Ollama. For detailed provider configuration and local model setup, see the [Installation Guide](getting-started/installation.md#choosing-your-llms).
50 +> Agent Zero supports any LLM provider, including local models via Ollama. For detailed provider configuration and local model setup, see the [Installation Guide](setup/installation.md#choosing-your-llms).
51
52 ### Step 5: Start Your First Chat
53
@@ -95,3 +95,7 @@ Now that you've run a simple task, you can experiment with more complex requests
95
96 Provides more in-depth information on tools, projects, tasks, and backup/restore.
97
98 +## 🎓 Video Tutorials
99 +- [MCP Server Setup](https://youtu.be/pM5f4Vz3_IQ)
100 +- [Projects & Workspaces](https://youtu.be/RrTDp_v9V1c)
101 +- [Memory Management](https://youtu.be/sizjAq2-d9s)
docs/res/081_vid.png
Binary files a/docs/res/081_vid.png and /dev/null differ
docs/res/arch-01.svg deleted
-1406
@@ -1,1406 +0,0 @@
1 -<?xml version="1.0" encoding="utf-8"?>
2 -<!-- Generator: Adobe Illustrator 27.9.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3 -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4 - viewBox="0 0 2493.1 633.4" style="enable-background:new 0 0 2493.1 633.4;" xml:space="preserve">
5 -<style type="text/css">
6 - .st0{clip-path:url(#SVGID_00000034794952764765167540000017453395941957106569_);}
7 - .st1{fill:none;stroke:#D3D3D3;stroke-width:6.93;}
8 - .st2{clip-path:url(#SVGID_00000053535984049889517880000007059510055645152906_);}
9 - .st3{fill:#D3D3D3;}
10 - .st4{clip-path:url(#SVGID_00000179642885161553590150000011886740614098073247_);}
11 - .st5{clip-path:url(#SVGID_00000036946105526205689300000005607100343215513016_);}
12 - .st6{clip-path:url(#SVGID_00000134958289911380505240000000661052948126753668_);}
13 - .st7{clip-path:url(#SVGID_00000062914314161677759140000000216015874320241080_);}
14 - .st8{clip-path:url(#SVGID_00000090258142172699109740000003094644549775752320_);}
15 - .st9{clip-path:url(#SVGID_00000139985350880984363370000016693915801870095790_);}
16 - .st10{clip-path:url(#SVGID_00000080927568956747538760000016564597446575268014_);}
17 - .st11{clip-path:url(#SVGID_00000114773121177082384380000006987802019000660641_);}
18 - .st12{clip-path:url(#SVGID_00000065065194367023870170000005385116056721570222_);}
19 - .st13{clip-path:url(#SVGID_00000076593837993558435330000015985317974184574117_);}
20 - .st14{clip-path:url(#SVGID_00000171682719945064759640000017232705029243799947_);}
21 - .st15{clip-path:url(#SVGID_00000119811199724697527700000016537644700294537881_);}
22 - .st16{clip-path:url(#SVGID_00000022554932680127080920000016386081719414704060_);}
23 - .st17{clip-path:url(#SVGID_00000162335221531095132520000007588219742315599756_);}
24 - .st18{clip-path:url(#SVGID_00000029755533516621035270000004212564493506491300_);}
25 - .st19{clip-path:url(#SVGID_00000022537942952607575120000000358127970904958628_);}
26 - .st20{clip-path:url(#SVGID_00000085243054380376171920000014129426332246507683_);}
27 - .st21{clip-path:url(#SVGID_00000168093319386610208390000017334500852477807288_);}
28 - .st22{clip-path:url(#SVGID_00000037660396531444051120000011254822278301144489_);}
29 - .st23{clip-path:url(#SVGID_00000059293400734983706550000000467256514231523716_);}
30 - .st24{clip-path:url(#SVGID_00000020376401862210930640000011744918560168611497_);}
31 - .st25{clip-path:url(#SVGID_00000125576015166639624960000006054719046018963600_);}
32 - .st26{clip-path:url(#SVGID_00000007388351403635333730000005786079104813236664_);}
33 - .st27{fill:none;stroke:#D3D3D3;stroke-width:1.98;}
34 - .st28{clip-path:url(#SVGID_00000075131101690320623840000012717898997225819037_);}
35 - .st29{clip-path:url(#SVGID_00000078040978912162548410000015122729567343600524_);}
36 - .st30{clip-path:url(#SVGID_00000140709273767330474510000001969146524822839482_);}
37 - .st31{clip-path:url(#SVGID_00000142898451440700522840000003886579701637536695_);}
38 - .st32{clip-path:url(#SVGID_00000163060132144427967970000001859679130760294019_);}
39 - .st33{clip-path:url(#SVGID_00000112624950726163281240000005582900153381669553_);}
40 - .st34{clip-path:url(#SVGID_00000040543625480926530060000001934506048120145596_);}
41 - .st35{clip-path:url(#SVGID_00000072258171003495978090000014599790566241796021_);}
42 - .st36{clip-path:url(#SVGID_00000177447879008588078010000012584708919575946166_);}
43 - .st37{clip-path:url(#SVGID_00000145053579310733024350000008118751303325226373_);}
44 - .st38{clip-path:url(#SVGID_00000009569840294732083430000012103543713112139650_);}
45 - .st39{clip-path:url(#SVGID_00000019656390759610240330000014236852445514954130_);}
46 - .st40{clip-path:url(#SVGID_00000150075729330479933410000008246244144320733861_);}
47 - .st41{clip-path:url(#SVGID_00000034066801346939966520000002459740041161992603_);}
48 - .st42{clip-path:url(#SVGID_00000038387558610613029720000001649334070747303057_);}
49 - .st43{clip-path:url(#SVGID_00000028299304737208287410000008091384729759149960_);}
50 - .st44{clip-path:url(#SVGID_00000154386378122082840670000011193901317889213335_);}
51 - .st45{clip-path:url(#SVGID_00000158750787163577526010000004269989998965558146_);}
52 - .st46{clip-path:url(#SVGID_00000040570725969151952400000001149167639168650670_);}
53 - .st47{clip-path:url(#SVGID_00000071530591416548135110000007154994753142013834_);}
54 - .st48{clip-path:url(#SVGID_00000045620052656141231530000010490338008905645995_);}
55 - .st49{clip-path:url(#SVGID_00000164502409285600606920000009463440726942061228_);}
56 - .st50{clip-path:url(#SVGID_00000139294915294798377430000004323687035197998756_);}
57 - .st51{clip-path:url(#SVGID_00000160176853433453049690000000623804333935792301_);}
58 - .st52{clip-path:url(#SVGID_00000008129363442407892600000005743236523376768388_);}
59 - .st53{clip-path:url(#SVGID_00000001657407307513980710000009952733119759238828_);}
60 - .st54{clip-path:url(#SVGID_00000155848760482230012960000017190433946091079583_);}
61 - .st55{clip-path:url(#SVGID_00000062910701951078671830000012771503644750027680_);}
62 - .st56{clip-path:url(#SVGID_00000095338738245058189100000004651375019311818887_);}
63 - .st57{clip-path:url(#SVGID_00000117667925917670668490000017117517095186750897_);}
64 - .st58{clip-path:url(#SVGID_00000144335053720426228400000012976542417071411086_);}
65 - .st59{clip-path:url(#SVGID_00000103264747217563404370000007145305442971024275_);}
66 - .st60{clip-path:url(#SVGID_00000120550786379034537350000014361786292651581568_);}
67 - .st61{clip-path:url(#SVGID_00000016042976806763532980000000122038520491041465_);}
68 - .st62{clip-path:url(#SVGID_00000019636689222305984910000007160081465036709818_);}
69 - .st63{clip-path:url(#SVGID_00000176736978719676321710000002959120663620848283_);}
70 - .st64{fill:#004488;}
71 - .st65{fill:none;stroke:#000000;stroke-width:3.96;}
72 - .st66{clip-path:url(#SVGID_00000057106282352734447800000001035521247852850817_);}
73 - .st67{fill:#CCCCCC;}
74 - .st68{font-family:'TrebuchetMS';}
75 - .st69{font-size:31.69px;}
76 - .st70{clip-path:url(#SVGID_00000054986550691091659410000017012437047206080908_);}
77 - .st71{clip-path:url(#SVGID_00000046298146094813883400000012487650457855404930_);}
78 - .st72{clip-path:url(#SVGID_00000149363274087029293490000007331231945051125688_);}
79 - .st73{fill:#333333;}
80 - .st74{fill:none;stroke:#555555;stroke-width:3.96;}
81 - .st75{clip-path:url(#SVGID_00000032618697040894825750000010230463812730257328_);}
82 - .st76{clip-path:url(#SVGID_00000052098106255301652160000007916102991940594866_);}
83 - .st77{clip-path:url(#SVGID_00000084491580938088296150000001522206945574606984_);}
84 - .st78{clip-path:url(#SVGID_00000039135598203949472300000014602150438437345929_);}
85 - .st79{clip-path:url(#SVGID_00000144329036219736207450000009581474905475309224_);}
86 - .st80{clip-path:url(#SVGID_00000012450774490363338590000005467888255691828383_);}
87 - .st81{clip-path:url(#SVGID_00000049900582787347099940000000222156239313180805_);}
88 - .st82{clip-path:url(#SVGID_00000134242015010932658030000012000804311614169010_);}
89 - .st83{clip-path:url(#SVGID_00000125580238055646825090000002312525002594201772_);}
90 - .st84{clip-path:url(#SVGID_00000152236498460011615740000005808167675324029828_);}
91 - .st85{clip-path:url(#SVGID_00000174592270447031484130000001183534740213604278_);}
92 -</style>
93 -<g>
94 - <defs>
95 - <rect id="SVGID_1_" x="10" y="-315.3" width="2473" height="1264"/>
96 - </defs>
97 - <clipPath id="SVGID_00000128479878146722190600000017293108473233837988_">
98 - <use xlink:href="#SVGID_1_" style="overflow:visible;"/>
99 - </clipPath>
100 -</g>
101 -<g>
102 - <defs>
103 - <rect id="SVGID_00000156582490830701867950000007420717187742836911_" x="10" y="-315.3" width="2473" height="1264"/>
104 - </defs>
105 - <clipPath id="SVGID_00000034778397228524758800000009878757437047714704_">
106 - <use xlink:href="#SVGID_00000156582490830701867950000007420717187742836911_" style="overflow:visible;"/>
107 - </clipPath>
108 - <g style="clip-path:url(#SVGID_00000034778397228524758800000009878757437047714704_);">
109 - <path class="st1" d="M194.4,93.1h15c15,0,44.9,0,63.9,0.6s27.3,1.8,34.3,2.9c7,1,12.6,1.9,15.4,2.3l2.8,0.4"/>
110 - </g>
111 -</g>
112 -<g>
113 - <defs>
114 - <rect id="SVGID_00000147221692991150647690000002984182599045136266_" x="187.3" y="85.2" width="15.8" height="15.8"/>
115 - </defs>
116 - <clipPath id="SVGID_00000011737623660742278070000015218363256941338036_">
117 - <use xlink:href="#SVGID_00000147221692991150647690000002984182599045136266_" style="overflow:visible;"/>
118 - </clipPath>
119 - <g style="clip-path:url(#SVGID_00000011737623660742278070000015218363256941338036_);">
120 - <polygon class="st3" points="187.3,93.1 203.1,101 203.1,85.2 "/>
121 - <path class="st3" d="M188.1,93.6l-0.5,0.3l-0.4-0.7l0.4-0.7l1.4,0.7l-0.7,1.4l-2.8-1.4l1.9-1L188.1,93.6L188.1,93.6z M189.6,92.9
122 - l-1.4,0.7l-0.7-1.4l1.4-0.7L189.6,92.9z M191,92.2l-1.4,0.7l-0.7-1.4l1.4-0.7L191,92.2z M192.4,91.4l-1.4,0.7l-0.7-1.4l1.4-0.7
123 - L192.4,91.4z M193.8,90.7l-1.4,0.7l-0.7-1.4l1.4-0.7L193.8,90.7z M195.2,90l-1.4,0.7l-0.7-1.4l1.4-0.7L195.2,90z M196.7,89.3
124 - l-1.4,0.7l-0.7-1.4l1.4-0.7L196.7,89.3z M198.1,88.6l-1.4,0.7l-0.7-1.4l1.4-0.7L198.1,88.6z M199.5,87.9l-1.4,0.7l-0.7-1.4
125 - l1.4-0.7L199.5,87.9z M200.9,87.2l-1.4,0.7l-0.7-1.4l1.4-0.7L200.9,87.2z M202.3,86.5l-1.4,0.7l-0.7-1.4l1.4-0.7L202.3,86.5z
126 - M202.4,85.5v-0.3h0.8l0.4,0.7l-1.2,0.6l-0.7-1.4l2.3-1.2v1.6H202.4L202.4,85.5z M202.4,87.1v-1.6h1.6v1.6H202.4z M202.4,88.6
127 - v-1.6h1.6v1.6H202.4z M202.4,90.2v-1.6h1.6v1.6H202.4z M202.4,91.8v-1.6h1.6v1.6H202.4z M202.4,93.4v-1.6h1.6v1.6H202.4z
128 - M202.4,95v-1.6h1.6V95H202.4z M202.4,96.5V95h1.6v1.6H202.4z M202.4,98.1v-1.6h1.6v1.6H202.4z M202.4,99.7v-1.6h1.6v1.6H202.4z
129 - M203.2,100.2l0.3,0.1l-0.4,0.7h-0.8v-1.3h1.6v2.6l-1.4-0.7L203.2,100.2L203.2,100.2z M201.8,99.4l1.4,0.7l-0.7,1.4l-1.4-0.7
130 - L201.8,99.4z M200.4,98.7l1.4,0.7l-0.7,1.4l-1.4-0.7L200.4,98.7z M199,98l1.4,0.7l-0.7,1.4l-1.4-0.7L199,98z M197.6,97.3L199,98
131 - l-0.7,1.4l-1.4-0.7L197.6,97.3z M196.1,96.6l1.4,0.7l-0.7,1.4l-1.4-0.7L196.1,96.6z M194.7,95.9l1.4,0.7l-0.7,1.4l-1.4-0.7
132 - L194.7,95.9z M193.3,95.2l1.4,0.7l-0.7,1.4l-1.4-0.7L193.3,95.2z M191.9,94.5l1.4,0.7l-0.7,1.4l-1.4-0.7L191.9,94.5z M190.5,93.8
133 - l1.4,0.7l-0.7,1.4l-1.4-0.7L190.5,93.8z M189.1,93.1l1.4,0.7l-0.7,1.4l-1.4-0.7L189.1,93.1z"/>
134 - </g>
135 -</g>
136 -<g>
137 - <defs>
138 - <rect id="SVGID_00000093858751899835667100000013449994690334507404_" x="10" y="-315.3" width="2473" height="1264"/>
139 - </defs>
140 - <clipPath id="SVGID_00000162318200989428133210000015775779535705021630_">
141 - <use xlink:href="#SVGID_00000093858751899835667100000013449994690334507404_" style="overflow:visible;"/>
142 - </clipPath>
143 - <g style="clip-path:url(#SVGID_00000162318200989428133210000015775779535705021630_);">
144 - <g>
145 - <defs>
146 - <rect id="SVGID_00000112616417274699953940000015266884599994592911_" x="10" y="-315.3" width="2473" height="1264"/>
147 - </defs>
148 - <clipPath id="SVGID_00000014617277928488838120000008265875186815129764_">
149 - <use xlink:href="#SVGID_00000112616417274699953940000015266884599994592911_" style="overflow:visible;"/>
150 - </clipPath>
151 - <g style="clip-path:url(#SVGID_00000014617277928488838120000008265875186815129764_);">
152 - <g>
153 - <defs>
154 -
155 - <rect id="SVGID_00000092420812503207798460000005381030821375817624_" x="317.9" y="91.4" transform="matrix(0.1473 -0.9891 0.9891 0.1473 179.5882 406.9542)" width="15.8" height="15.8"/>
156 - </defs>
157 - <clipPath id="SVGID_00000052806194870497224950000002037089886787165591_">
158 - <use xlink:href="#SVGID_00000092420812503207798460000005381030821375817624_" style="overflow:visible;"/>
159 - </clipPath>
160 - <g style="clip-path:url(#SVGID_00000052806194870497224950000002037089886787165591_);">
161 - <polygon class="st3" points="319.1,90.3 333.6,100.5 316.8,106 "/>
162 - <path class="st3" d="M318.3,90.8l0.3-1.8l2.4,1.7l-0.9,1.3l-1.3-0.9l0.5-0.7l0.8,0.1l-0.1,0.6L318.3,90.8L318.3,90.8z
163 - M318,92.3l0.2-1.6l1.6,0.2l-0.2,1.6L318,92.3z M317.8,93.9l0.2-1.6l1.6,0.2l-0.2,1.6L317.8,93.9z M317.6,95.5l0.2-1.6
164 - l1.6,0.2l-0.2,1.6L317.6,95.5z M317.3,97l0.2-1.6l1.6,0.2l-0.2,1.6L317.3,97z M317.1,98.6l0.2-1.6l1.6,0.2l-0.2,1.6
165 - L317.1,98.6z M316.9,100.2l0.2-1.6l1.6,0.2l-0.2,1.6L316.9,100.2z M316.7,101.8l0.2-1.6l1.6,0.2l-0.2,1.6L316.7,101.8z
166 - M316.4,103.3l0.2-1.6l1.6,0.2l-0.2,1.6L316.4,103.3z M316.2,104.9l0.2-1.6l1.6,0.2l-0.2,1.6L316.2,104.9z M317.6,106.6
167 - l-1.8,0.6l0.3-2.3l1.6,0.2l-0.1,1l-0.8-0.1l-0.2-0.8l0.5-0.2C317.1,105.1,317.6,106.6,317.6,106.6z M319.1,106.1l-1.5,0.5
168 - l-0.5-1.5l1.5-0.5L319.1,106.1z M320.6,105.6l-1.5,0.5l-0.5-1.5l1.5-0.5L320.6,105.6z M322.1,105.1l-1.5,0.5l-0.5-1.5l1.5-0.5
169 - L322.1,105.1z M323.7,104.6l-1.5,0.5l-0.5-1.5l1.5-0.5L323.7,104.6z M325.2,104.1l-1.5,0.5l-0.5-1.5l1.5-0.5L325.2,104.1z
170 - M326.7,103.6l-1.5,0.5l-0.5-1.5l1.5-0.5L326.7,103.6z M328.2,103.2l-1.5,0.5l-0.5-1.5l1.5-0.5L328.2,103.2z M329.7,102.7
171 - l-1.5,0.5l-0.5-1.5l1.5-0.5L329.7,102.7z M331.2,102.2l-1.5,0.5l-0.5-1.5l1.5-0.5L331.2,102.2z M332.7,101.7l-1.5,0.5
172 - l-0.5-1.5l1.5-0.5L332.7,101.7z M333.9,99.7l1.5,1.1l-2.7,0.9l-0.5-1.5l1.2-0.4l0.2,0.8l-0.5,0.7L333,101L333.9,99.7
173 - L333.9,99.7z M332.6,98.8l1.3,0.9L333,101l-1.3-0.9L332.6,98.8z M331.3,97.9l1.3,0.9l-0.9,1.3l-1.3-0.9L331.3,97.9z M330,97
174 - l1.3,0.9l-0.9,1.3l-1.3-0.9L330,97z M328.7,96.1L330,97l-0.9,1.3l-1.3-0.9L328.7,96.1z M327.4,95.2l1.3,0.9l-0.9,1.3l-1.3-0.9
175 - L327.4,95.2z M326.1,94.3l1.3,0.9l-0.9,1.3l-1.3-0.9L326.1,94.3z M324.8,93.3l1.3,0.9l-0.9,1.3l-1.3-0.9L324.8,93.3z
176 - M323.5,92.4l1.3,0.9l-0.9,1.3l-1.3-0.9L323.5,92.4z M322.2,91.5l1.3,0.9l-0.9,1.3l-1.3-0.9L322.2,91.5z M320.9,90.6l1.3,0.9
177 - l-0.9,1.3l-1.3-0.9L320.9,90.6z"/>
178 - </g>
179 - </g>
180 - </g>
181 - </g>
182 - </g>
183 -</g>
184 -<g>
185 - <defs>
186 - <rect id="SVGID_00000070823444115619774530000000212636115607913902_" x="10" y="-315.3" width="2473" height="1264"/>
187 - </defs>
188 - <clipPath id="SVGID_00000155842565674748166340000017269588663572040100_">
189 - <use xlink:href="#SVGID_00000070823444115619774530000000212636115607913902_" style="overflow:visible;"/>
190 - </clipPath>
191 - <g style="clip-path:url(#SVGID_00000155842565674748166340000017269588663572040100_);">
192 - <path class="st1" d="M507.9,162.8l7.1,3.9c7.1,3.9,21.3,11.7,32.5,17.2S567,192.4,574,195c7,2.6,12.8,4.8,15.7,5.9l2.9,1.1"/>
193 - </g>
194 -</g>
195 -<g>
196 - <defs>
197 - <rect id="SVGID_00000042010673593885909540000014996048614314277260_" x="10" y="-315.3" width="2473" height="1264"/>
198 - </defs>
199 - <clipPath id="SVGID_00000070088212485098816520000002564726131767061122_">
200 - <use xlink:href="#SVGID_00000042010673593885909540000014996048614314277260_" style="overflow:visible;"/>
201 - </clipPath>
202 - <g style="clip-path:url(#SVGID_00000070088212485098816520000002564726131767061122_);">
203 - <g>
204 - <defs>
205 - <rect id="SVGID_00000029012379620026162070000003324866748670628789_" x="10" y="-315.3" width="2473" height="1264"/>
206 - </defs>
207 - <clipPath id="SVGID_00000073695375304384808230000018159882394806530987_">
208 - <use xlink:href="#SVGID_00000029012379620026162070000003324866748670628789_" style="overflow:visible;"/>
209 - </clipPath>
210 - <g style="clip-path:url(#SVGID_00000073695375304384808230000018159882394806530987_);">
211 - <g>
212 - <defs>
213 -
214 - <rect id="SVGID_00000167388079833758191900000004549096807954218679_" x="500.7" y="155.2" transform="matrix(0.4821 -0.8761 0.8761 0.4821 120.4845 530.1118)" width="15.8" height="15.8"/>
215 - </defs>
216 - <clipPath id="SVGID_00000097471929231050799960000013280947045189128096_">
217 - <use xlink:href="#SVGID_00000167388079833758191900000004549096807954218679_" style="overflow:visible;"/>
218 - </clipPath>
219 - <g style="clip-path:url(#SVGID_00000097471929231050799960000013280947045189128096_);">
220 - <polygon class="st3" points="501.7,159.3 511.7,173.9 519.4,160 "/>
221 - <path class="st3" d="M502.2,160.2l-0.6,0l0-0.8l0.6-0.4l0.9,1.3l-1.3,0.9l-1.8-2.6l2.1,0.1L502.2,160.2L502.2,160.2z
222 - M503.8,160.2l-1.6-0.1l0.1-1.6l1.6,0.1L503.8,160.2z M505.4,160.3l-1.6-0.1l0.1-1.6l1.6,0.1L505.4,160.3z M507,160.3
223 - l-1.6-0.1l0.1-1.6l1.6,0.1L507,160.3z M508.5,160.4l-1.6-0.1l0.1-1.6l1.6,0.1L508.5,160.4z M510.1,160.4l-1.6-0.1l0.1-1.6
224 - l1.6,0.1L510.1,160.4z M511.7,160.5l-1.6-0.1l0.1-1.6l1.6,0.1L511.7,160.5z M513.3,160.6l-1.6-0.1l0.1-1.6l1.6,0.1
225 - L513.3,160.6z M514.9,160.6l-1.6-0.1l0.1-1.6l1.6,0.1L514.9,160.6z M516.4,160.7l-1.6-0.1l0.1-1.6l1.6,0.1L516.4,160.7z
226 - M518,160.7l-1.6-0.1l0.1-1.6l1.6,0.1L518,160.7z M518.5,159.9l0.1-0.2l0.7,0.4l0,0.8l-1.3-0.1l0.1-1.6l2.6,0.1l-0.8,1.4
227 - L518.5,159.9L518.5,159.9z M517.8,161.3l0.8-1.4l1.4,0.8l-0.8,1.4L517.8,161.3z M517,162.7l0.8-1.4l1.4,0.8l-0.8,1.4
228 - L517,162.7z M516.2,164l0.8-1.4l1.4,0.8l-0.8,1.4L516.2,164z M515.5,165.4l0.8-1.4l1.4,0.8l-0.8,1.4L515.5,165.4z
229 - M514.7,166.8l0.8-1.4l1.4,0.8l-0.8,1.4L514.7,166.8z M514,168.2l0.8-1.4l1.4,0.8l-0.8,1.4L514,168.2z M513.2,169.6l0.8-1.4
230 - l1.4,0.8l-0.8,1.4L513.2,169.6z M512.4,171l0.8-1.4l1.4,0.8l-0.8,1.4L512.4,171z M511.7,172.4l0.8-1.4l1.4,0.8l-0.8,1.4
231 - L511.7,172.4z M512.2,173.2l0.2,0.2l-0.6,0.4l-0.7-0.4l0.6-1.1l1.4,0.8l-1.2,2.3l-0.9-1.3L512.2,173.2L512.2,173.2z
232 - M511.3,171.9l0.9,1.3l-1.3,0.9l-0.9-1.3L511.3,171.9z M510.4,170.6l0.9,1.3l-1.3,0.9l-0.9-1.3L510.4,170.6z M509.5,169.3
233 - l0.9,1.3l-1.3,0.9l-0.9-1.3L509.5,169.3z M508.6,168l0.9,1.3l-1.3,0.9l-0.9-1.3L508.6,168z M507.7,166.7l0.9,1.3l-1.3,0.9
234 - l-0.9-1.3L507.7,166.7z M506.8,165.4l0.9,1.3l-1.3,0.9l-0.9-1.3L506.8,165.4z M505.9,164.1l0.9,1.3l-1.3,0.9l-0.9-1.3
235 - L505.9,164.1z M505,162.8l0.9,1.3l-1.3,0.9l-0.9-1.3L505,162.8z M504.1,161.5l0.9,1.3l-1.3,0.9l-0.9-1.3L504.1,161.5z
236 - M503.2,160.2l0.9,1.3l-1.3,0.9l-0.9-1.3L503.2,160.2z"/>
237 - </g>
238 - </g>
239 - </g>
240 - </g>
241 - </g>
242 -</g>
243 -<g>
244 - <defs>
245 - <rect id="SVGID_00000049943544227308376000000007072169369243641257_" x="10" y="-315.3" width="2473" height="1264"/>
246 - </defs>
247 - <clipPath id="SVGID_00000103234997372834954530000006174341272453330569_">
248 - <use xlink:href="#SVGID_00000049943544227308376000000007072169369243641257_" style="overflow:visible;"/>
249 - </clipPath>
250 - <g style="clip-path:url(#SVGID_00000103234997372834954530000006174341272453330569_);">
251 - <g>
252 - <defs>
253 - <rect id="SVGID_00000158018415820235133740000002066697186618387614_" x="10" y="-315.3" width="2473" height="1264"/>
254 - </defs>
255 - <clipPath id="SVGID_00000012453738737432636320000013378560366222779017_">
256 - <use xlink:href="#SVGID_00000158018415820235133740000002066697186618387614_" style="overflow:visible;"/>
257 - </clipPath>
258 - <g style="clip-path:url(#SVGID_00000012453738737432636320000013378560366222779017_);">
259 - <g>
260 - <defs>
261 -
262 - <rect id="SVGID_00000094603824151318940220000009156750148571216798_" x="584.7" y="194" transform="matrix(0.3505 -0.9365 0.9365 0.3505 195.7393 686.1675)" width="15.8" height="15.8"/>
263 - </defs>
264 - <clipPath id="SVGID_00000133526439638024974870000007130657155689240975_">
265 - <use xlink:href="#SVGID_00000094603824151318940220000009156750148571216798_" style="overflow:visible;"/>
266 - </clipPath>
267 - <g style="clip-path:url(#SVGID_00000133526439638024974870000007130657155689240975_);">
268 - <polygon class="st3" points="587.9,191.7 600,204.7 582.4,206.6 "/>
269 - <path class="st3" d="M587,192l0.7-1.7l2,2.1l-1.2,1.1l-1.1-1.2l0.6-0.5l0.7,0.3l-0.2,0.5L587,192L587,192z M586.4,193.5
270 - l0.6-1.5l1.5,0.6l-0.6,1.5L586.4,193.5z M585.9,195l0.6-1.5l1.5,0.6l-0.6,1.5L585.9,195z M585.3,196.4l0.6-1.5l1.5,0.6
271 - l-0.6,1.5L585.3,196.4z M584.8,197.9l0.6-1.5l1.5,0.6l-0.6,1.5L584.8,197.9z M584.2,199.4l0.6-1.5l1.5,0.6l-0.6,1.5
272 - L584.2,199.4z M583.6,200.9l0.6-1.5l1.5,0.6l-0.6,1.5L583.6,200.9z M583.1,202.4l0.6-1.5l1.5,0.6l-0.6,1.5L583.1,202.4z
273 - M582.5,203.8l0.6-1.5l1.5,0.6l-0.6,1.5L582.5,203.8z M582,205.3l0.6-1.5l1.5,0.6l-0.6,1.5L582,205.3z M583,207.3l-1.8,0.2
274 - l0.8-2.1l1.5,0.6l-0.3,0.9l-0.7-0.3l-0.1-0.8l0.6-0.1L583,207.3L583,207.3z M584.6,207.1l-1.6,0.2l-0.2-1.6l1.6-0.2
275 - L584.6,207.1z M586.2,206.9l-1.6,0.2l-0.2-1.6l1.6-0.2L586.2,206.9z M587.7,206.8l-1.6,0.2l-0.2-1.6l1.6-0.2L587.7,206.8z
276 - M589.3,206.6l-1.6,0.2l-0.2-1.6l1.6-0.2L589.3,206.6z M590.9,206.4l-1.6,0.2l-0.2-1.6l1.6-0.2L590.9,206.4z M592.5,206.2
277 - l-1.6,0.2l-0.2-1.6l1.6-0.2L592.5,206.2z M594.1,206.1l-1.6,0.2l-0.2-1.6l1.6-0.2L594.1,206.1z M595.6,205.9l-1.6,0.2
278 - l-0.2-1.6l1.6-0.2L595.6,205.9z M597.2,205.7l-1.6,0.2l-0.2-1.6l1.6-0.2L597.2,205.7z M598.8,205.6l-1.6,0.2l-0.2-1.6l1.6-0.2
279 - L598.8,205.6z M600.4,203.9l1.3,1.4l-2.9,0.3l-0.2-1.6l1.3-0.1l0.1,0.8l-0.6,0.5l-0.2-0.2L600.4,203.9L600.4,203.9z
280 - M599.3,202.7l1.1,1.2l-1.2,1.1l-1.1-1.2L599.3,202.7z M598.2,201.6l1.1,1.2l-1.2,1.1l-1.1-1.2L598.2,201.6z M597.2,200.4
281 - l1.1,1.2l-1.2,1.1l-1.1-1.2L597.2,200.4z M596.1,199.2l1.1,1.2l-1.2,1.1l-1.1-1.2L596.1,199.2z M595,198.1l1.1,1.2l-1.2,1.1
282 - l-1.1-1.2L595,198.1z M593.9,196.9l1.1,1.2l-1.2,1.1l-1.1-1.2L593.9,196.9z M592.8,195.8l1.1,1.2l-1.2,1.1l-1.1-1.2
283 - L592.8,195.8z M591.8,194.6l1.1,1.2l-1.2,1.1l-1.1-1.2L591.8,194.6z M590.7,193.4l1.1,1.2l-1.2,1.1l-1.1-1.2L590.7,193.4z
284 - M589.6,192.3l1.1,1.2l-1.2,1.1l-1.1-1.2L589.6,192.3z"/>
285 - </g>
286 - </g>
287 - </g>
288 - </g>
289 - </g>
290 -</g>
291 -<g>
292 - <defs>
293 - <rect id="SVGID_00000087412035869008330150000013175557509581735077_" x="10" y="-315.3" width="2473" height="1264"/>
294 - </defs>
295 - <clipPath id="SVGID_00000103971478953225767130000008268232541468684980_">
296 - <use xlink:href="#SVGID_00000087412035869008330150000013175557509581735077_" style="overflow:visible;"/>
297 - </clipPath>
298 - <g style="clip-path:url(#SVGID_00000103971478953225767130000008268232541468684980_);">
299 - <path class="st1" d="M836.1,327.4l7.2,4.7c7.2,4.7,21.5,14.1,32.7,21.1s19.5,11.7,26.6,15.7s13.1,7.4,16,9.1l3,1.7"/>
300 - </g>
301 -</g>
302 -<g>
303 - <defs>
304 - <rect id="SVGID_00000178178560818696902800000007109673308086915743_" x="10" y="-315.3" width="2473" height="1264"/>
305 - </defs>
306 - <clipPath id="SVGID_00000176729557009616319830000009392807693212917689_">
307 - <use xlink:href="#SVGID_00000178178560818696902800000007109673308086915743_" style="overflow:visible;"/>
308 - </clipPath>
309 - <g style="clip-path:url(#SVGID_00000176729557009616319830000009392807693212917689_);">
310 - <g>
311 - <defs>
312 - <rect id="SVGID_00000040567733951681668980000001473299224116959390_" x="10" y="-315.3" width="2473" height="1264"/>
313 - </defs>
314 - <clipPath id="SVGID_00000066515416994184725830000016719911793883313037_">
315 - <use xlink:href="#SVGID_00000040567733951681668980000001473299224116959390_" style="overflow:visible;"/>
316 - </clipPath>
317 - <g style="clip-path:url(#SVGID_00000066515416994184725830000016719911793883313037_);">
318 - <g>
319 - <defs>
320 -
321 - <rect id="SVGID_00000070101701678282706610000017219180502046599098_" x="828.8" y="319.9" transform="matrix(0.5496 -0.8354 0.8354 0.5496 102.9782 846.7191)" width="15.8" height="15.8"/>
322 - </defs>
323 - <clipPath id="SVGID_00000047057298416053620940000015093769478039192708_">
324 - <use xlink:href="#SVGID_00000070101701678282706610000017219180502046599098_" style="overflow:visible;"/>
325 - </clipPath>
326 - <g style="clip-path:url(#SVGID_00000047057298416053620940000015093769478039192708_);">
327 - <polygon class="st3" points="830.1,323.5 839,338.8 847.7,325.5 "/>
328 - <path class="st3" d="M830.6,324.3l-0.6-0.1l0.1-0.8l0.7-0.4l0.8,1.4l-1.4,0.8l-1.6-2.7l2.1,0.2L830.6,324.3L830.6,324.3z
329 - M832.2,324.5l-1.6-0.2l0.2-1.6l1.6,0.2L832.2,324.5z M833.7,324.7l-1.6-0.2l0.2-1.6l1.6,0.2L833.7,324.7z M835.3,324.9
330 - l-1.6-0.2l0.2-1.6l1.6,0.2L835.3,324.9z M836.9,325.1l-1.6-0.2l0.2-1.6l1.6,0.2L836.9,325.1z M838.4,325.3l-1.6-0.2l0.2-1.6
331 - l1.6,0.2L838.4,325.3z M840,325.4l-1.6-0.2l0.2-1.6l1.6,0.2L840,325.4z M841.6,325.6l-1.6-0.2l0.2-1.6l1.6,0.2L841.6,325.6z
332 - M843.2,325.8l-1.6-0.2l0.2-1.6l1.6,0.2L843.2,325.8z M844.7,326l-1.6-0.2l0.2-1.6l1.6,0.2L844.7,326z M846.3,326.2l-1.6-0.2
333 - l0.2-1.6l1.6,0.2L846.3,326.2z M846.9,325.4l0.2-0.2l0.7,0.4l-0.1,0.8l-1.3-0.1l0.2-1.6l2.6,0.3l-0.9,1.3L846.9,325.4
334 - L846.9,325.4z M846,326.7l0.9-1.3l1.3,0.9l-0.9,1.3L846,326.7z M845.1,328l0.9-1.3l1.3,0.9l-0.9,1.3L845.1,328z M844.2,329.3
335 - l0.9-1.3l1.3,0.9l-0.9,1.3L844.2,329.3z M843.4,330.7l0.9-1.3l1.3,0.9l-0.9,1.3L843.4,330.7z M842.5,332l0.9-1.3l1.3,0.9
336 - l-0.9,1.3L842.5,332z M841.6,333.3l0.9-1.3l1.3,0.9l-0.9,1.3L841.6,333.3z M840.8,334.6l0.9-1.3l1.3,0.9l-0.9,1.3L840.8,334.6
337 - z M839.9,335.9l0.9-1.3l1.3,0.9l-0.9,1.3L839.9,335.9z M839,337.3l0.9-1.3l1.3,0.9l-0.9,1.3L839,337.3z M839.5,338.1l0.1,0.2
338 - l-0.7,0.4l-0.7-0.4l0.7-1.1l1.3,0.9l-1.4,2.2l-0.8-1.4L839.5,338.1L839.5,338.1z M838.7,336.8l0.8,1.4l-1.4,0.8l-0.8-1.4
339 - L838.7,336.8z M837.9,335.4l0.8,1.4l-1.4,0.8l-0.8-1.4L837.9,335.4z M837.1,334l0.8,1.4l-1.4,0.8l-0.8-1.4L837.1,334z
340 - M836.4,332.7l0.8,1.4l-1.4,0.8l-0.8-1.4L836.4,332.7z M835.6,331.3l0.8,1.4l-1.4,0.8l-0.8-1.4L835.6,331.3z M834.8,329.9
341 - l0.8,1.4l-1.4,0.8l-0.8-1.4L834.8,329.9z M834,328.6l0.8,1.4l-1.4,0.8l-0.8-1.4L834,328.6z M833.2,327.2l0.8,1.4l-1.4,0.8
342 - l-0.8-1.4L833.2,327.2z M832.4,325.8l0.8,1.4l-1.4,0.8l-0.8-1.4L832.4,325.8z M831.6,324.4l0.8,1.4l-1.4,0.8l-0.8-1.4
343 - L831.6,324.4z"/>
344 - </g>
345 - </g>
346 - </g>
347 - </g>
348 - </g>
349 -</g>
350 -<g>
351 - <defs>
352 - <rect id="SVGID_00000158000885227859372440000001146024053703914682_" x="10" y="-315.3" width="2473" height="1264"/>
353 - </defs>
354 - <clipPath id="SVGID_00000116203439053237544780000013188577553858990754_">
355 - <use xlink:href="#SVGID_00000158000885227859372440000001146024053703914682_" style="overflow:visible;"/>
356 - </clipPath>
357 - <g style="clip-path:url(#SVGID_00000116203439053237544780000013188577553858990754_);">
358 - <g>
359 - <defs>
360 - <rect id="SVGID_00000013898940300100481280000011238900852782555827_" x="10" y="-315.3" width="2473" height="1264"/>
361 - </defs>
362 - <clipPath id="SVGID_00000071547518409646732730000013168748332668814986_">
363 - <use xlink:href="#SVGID_00000013898940300100481280000011238900852782555827_" style="overflow:visible;"/>
364 - </clipPath>
365 - <g style="clip-path:url(#SVGID_00000071547518409646732730000013168748332668814986_);">
366 - <g>
367 - <defs>
368 -
369 - <rect id="SVGID_00000071561407548061813090000007278253983764529821_" x="913.7" y="371.8" transform="matrix(0.4929 -0.8701 0.8701 0.4929 136.9533 994.4316)" width="15.8" height="15.8"/>
370 - </defs>
371 - <clipPath id="SVGID_00000155137199540206869160000018124153452474560681_">
372 - <use xlink:href="#SVGID_00000071561407548061813090000007278253983764529821_" style="overflow:visible;"/>
373 - </clipPath>
374 - <g style="clip-path:url(#SVGID_00000155137199540206869160000018124153452474560681_);">
375 - <polygon class="st3" points="918.6,368.9 928.5,383.6 910.8,382.7 "/>
376 - <path class="st3" d="M917.6,369l0.9-1.6l1.6,2.4l-1.3,0.9l-0.9-1.3l0.7-0.4l0.7,0.4l-0.3,0.5L917.6,369L917.6,369z
377 - M916.8,370.4l0.8-1.4l1.4,0.8l-0.8,1.4L916.8,370.4z M916.1,371.8l0.8-1.4l1.4,0.8l-0.8,1.4L916.1,371.8z M915.3,373.2
378 - l0.8-1.4l1.4,0.8l-0.8,1.4L915.3,373.2z M914.5,374.6l0.8-1.4l1.4,0.8l-0.8,1.4L914.5,374.6z M913.7,375.9l0.8-1.4l1.4,0.8
379 - l-0.8,1.4L913.7,375.9z M912.9,377.3l0.8-1.4l1.4,0.8l-0.8,1.4L912.9,377.3z M912.2,378.7l0.8-1.4l1.4,0.8l-0.8,1.4
380 - L912.2,378.7z M911.4,380.1l0.8-1.4l1.4,0.8l-0.8,1.4L911.4,380.1z M910.6,381.5l0.8-1.4l1.4,0.8l-0.8,1.4L910.6,381.5z
381 - M911.3,383.6l-1.8-0.1l1.1-2l1.4,0.8l-0.5,0.9l-0.7-0.4l0-0.8l0.6,0L911.3,383.6L911.3,383.6z M912.9,383.6l-1.6-0.1l0.1-1.6
382 - l1.6,0.1L912.9,383.6z M914.5,383.7l-1.6-0.1l0.1-1.6l1.6,0.1L914.5,383.7z M916.1,383.8l-1.6-0.1l0.1-1.6l1.6,0.1
383 - L916.1,383.8z M917.6,383.9l-1.6-0.1l0.1-1.6l1.6,0.1L917.6,383.9z M919.2,384l-1.6-0.1l0.1-1.6l1.6,0.1L919.2,384z
384 - M920.8,384l-1.6-0.1l0.1-1.6l1.6,0.1L920.8,384z M922.4,384.1l-1.6-0.1l0.1-1.6l1.6,0.1L922.4,384.1z M924,384.2l-1.6-0.1
385 - l0.1-1.6l1.6,0.1L924,384.2z M925.5,384.3l-1.6-0.1l0.1-1.6l1.6,0.1L925.5,384.3z M927.1,384.3l-1.6-0.1l0.1-1.6l1.6,0.1
386 - L927.1,384.3z M929,382.9l1,1.5l-2.9-0.1l0.1-1.6l1.3,0.1l0,0.8l-0.7,0.4l-0.2-0.2L929,382.9L929,382.9z M928.1,381.6l0.9,1.3
387 - l-1.3,0.9l-0.9-1.3L928.1,381.6z M927.2,380.3l0.9,1.3l-1.3,0.9l-0.9-1.3L927.2,380.3L927.2,380.3z M926.3,379l0.9,1.3
388 - l-1.3,0.9l-0.9-1.3L926.3,379L926.3,379z M925.4,377.7l0.9,1.3l-1.3,0.9l-0.9-1.3L925.4,377.7L925.4,377.7z M924.6,376.4
389 - l0.9,1.3l-1.3,0.9l-0.9-1.3L924.6,376.4L924.6,376.4z M923.7,375.1l0.9,1.3l-1.3,0.9l-0.9-1.3L923.7,375.1L923.7,375.1z
390 - M922.8,373.8l0.9,1.3l-1.3,0.9l-0.9-1.3L922.8,373.8z M921.9,372.5l0.9,1.3l-1.3,0.9l-0.9-1.3L921.9,372.5z M921,371.1
391 - l0.9,1.3l-1.3,0.9l-0.9-1.3L921,371.1z M920.2,369.8l0.9,1.3l-1.3,0.9l-0.9-1.3L920.2,369.8z"/>
392 - </g>
393 - </g>
394 - </g>
395 - </g>
396 - </g>
397 -</g>
398 -<g>
399 - <defs>
400 - <rect id="SVGID_00000035521634753341000680000012734858015218667198_" x="10" y="-315.3" width="2473" height="1264"/>
401 - </defs>
402 - <clipPath id="SVGID_00000047034576383070236590000014123551028385855908_">
403 - <use xlink:href="#SVGID_00000035521634753341000680000012734858015218667198_" style="overflow:visible;"/>
404 - </clipPath>
405 - <g style="clip-path:url(#SVGID_00000047034576383070236590000014123551028385855908_);">
406 - <path class="st1" d="M441.5,173.8l18.2,45.8c18.2,45.8,54.5,137.4,100.1,183.3s100.3,45.8,155,45.8h205.8"/>
407 - </g>
408 -</g>
409 -<g>
410 - <defs>
411 - <rect id="SVGID_00000147934761108230763280000017430113123821613467_" x="10" y="-315.3" width="2473" height="1264"/>
412 - </defs>
413 - <clipPath id="SVGID_00000135673142993145490390000007931396453129175187_">
414 - <use xlink:href="#SVGID_00000147934761108230763280000017430113123821613467_" style="overflow:visible;"/>
415 - </clipPath>
416 - <g style="clip-path:url(#SVGID_00000135673142993145490390000007931396453129175187_);">
417 - <g>
418 - <defs>
419 - <rect id="SVGID_00000060010358776609352780000005425483684834936767_" x="10" y="-315.3" width="2473" height="1264"/>
420 - </defs>
421 - <clipPath id="SVGID_00000105428860904614489120000013518382021500096414_">
422 - <use xlink:href="#SVGID_00000060010358776609352780000005425483684834936767_" style="overflow:visible;"/>
423 - </clipPath>
424 - <g style="clip-path:url(#SVGID_00000105428860904614489120000013518382021500096414_);">
425 - <g>
426 - <defs>
427 -
428 - <rect id="SVGID_00000165930385459534158280000003776360454516865698_" x="433.8" y="166.5" transform="matrix(0.9295 -0.3688 0.3688 0.9295 -33.2018 175.1992)" width="15.8" height="15.8"/>
429 - </defs>
430 - <clipPath id="SVGID_00000072271210497258468200000013838592128057478558_">
431 - <use xlink:href="#SVGID_00000165930385459534158280000003776360454516865698_" style="overflow:visible;"/>
432 - </clipPath>
433 - <g style="clip-path:url(#SVGID_00000072271210497258468200000013838592128057478558_);">
434 - <polygon class="st3" points="438.8,167.1 437.3,184.8 452,178.9 "/>
435 - <path class="st3" d="M438.7,168.1l-0.4-0.4l0.5-0.6l0.8,0.1l-0.1,1.6l-1.6-0.1l0.3-3.2l1.6,1.4L438.7,168.1L438.7,168.1z
436 - M439.9,169.2l-1.2-1.1l1.1-1.2l1.2,1.1L439.9,169.2z M441.1,170.2l-1.2-1.1l1.1-1.2l1.2,1.1L441.1,170.2z M442.3,171.3
437 - l-1.2-1.1l1.1-1.2l1.2,1.1L442.3,171.3z M443.4,172.3l-1.2-1.1l1.1-1.2l1.2,1.1L443.4,172.3z M444.6,173.4l-1.2-1.1l1.1-1.2
438 - l1.2,1.1L444.6,173.4z M445.8,174.5l-1.2-1.1l1.1-1.2l1.2,1.1L445.8,174.5z M447,175.5l-1.2-1.1l1.1-1.2l1.2,1.1L447,175.5z
439 - M448.2,176.6l-1.2-1.1l1.1-1.2l1.2,1.1L448.2,176.6z M449.3,177.6l-1.2-1.1l1.1-1.2l1.2,1.1L449.3,177.6z M450.5,178.7
440 - l-1.2-1.1l1.1-1.2l1.2,1.1L450.5,178.7z M451.5,178.3l0.3-0.1l0.3,0.7l-0.5,0.6l-1-0.9l1.1-1.2l1.9,1.7l-1.5,0.6L451.5,178.3
441 - L451.5,178.3z M450,178.9l1.5-0.6l0.6,1.5l-1.5,0.6L450,178.9z M448.5,179.5l1.5-0.6l0.6,1.5l-1.5,0.6L448.5,179.5z
442 - M447,180.1l1.5-0.6l0.6,1.5l-1.5,0.6L447,180.1z M445.6,180.7l1.5-0.6l0.6,1.5l-1.5,0.6L445.6,180.7z M444.1,181.2l1.5-0.6
443 - l0.6,1.5l-1.5,0.6L444.1,181.2z M442.6,181.8l1.5-0.6l0.6,1.5l-1.5,0.6L442.6,181.8z M441.2,182.4l1.5-0.6l0.6,1.5l-1.5,0.6
444 - L441.2,182.4z M439.7,183l1.5-0.6l0.6,1.5l-1.5,0.6L439.7,183z M438.2,183.6l1.5-0.6l0.6,1.5l-1.5,0.6L438.2,183.6z
445 - M438.1,184.6l0,0.3l-0.8-0.1L437,184l1.2-0.5l0.6,1.5l-2.4,0.9l0.1-1.6L438.1,184.6L438.1,184.6z M438.3,183l-0.1,1.6
446 - l-1.6-0.1l0.1-1.6L438.3,183z M438.4,181.4l-0.1,1.6l-1.6-0.1l0.1-1.6L438.4,181.4z M438.5,179.8l-0.1,1.6l-1.6-0.1l0.1-1.6
447 - L438.5,179.8z M438.7,178.2l-0.1,1.6l-1.6-0.1l0.1-1.6L438.7,178.2z M438.8,176.7l-0.1,1.6l-1.6-0.1l0.1-1.6L438.8,176.7z
448 - M439,175.1l-0.1,1.6l-1.6-0.1l0.1-1.6L439,175.1z M439.1,173.5l-0.1,1.6l-1.6-0.1l0.1-1.6L439.1,173.5z M439.3,171.9
449 - l-0.1,1.6l-1.6-0.1l0.1-1.6L439.3,171.9z M439.4,170.3l-0.1,1.6l-1.6-0.1l0.1-1.6L439.4,170.3z M439.5,168.8l-0.1,1.6
450 - l-1.6-0.1l0.1-1.6L439.5,168.8z"/>
451 - </g>
452 - </g>
453 - </g>
454 - </g>
455 - </g>
456 -</g>
457 -<g>
458 - <defs>
459 - <rect id="SVGID_00000010285255016804533890000011192156035770591156_" x="912.6" y="440.7" width="15.8" height="15.8"/>
460 - </defs>
461 - <clipPath id="SVGID_00000089563400589899843860000001786002479704280226_">
462 - <use xlink:href="#SVGID_00000010285255016804533890000011192156035770591156_" style="overflow:visible;"/>
463 - </clipPath>
464 - <g style="clip-path:url(#SVGID_00000089563400589899843860000001786002479704280226_);">
465 - <polygon class="st3" points="912.6,440.7 928.5,448.6 912.6,456.6 "/>
466 - <path class="st3" d="M911.8,441.3v-1.9l2.6,1.3l-0.7,1.4l-1.4-0.7l0.3-0.7h0.8v0.6L911.8,441.3L911.8,441.3z M911.8,442.9v-1.6
467 - h1.6v1.6H911.8z M911.8,444.5v-1.6h1.6v1.6H911.8z M911.8,446v-1.6h1.6v1.6H911.8z M911.8,447.6V446h1.6v1.6H911.8z M911.8,449.2
468 - v-1.6h1.6v1.6H911.8z M911.8,450.8v-1.6h1.6v1.6H911.8z M911.8,452.4v-1.6h1.6v1.6H911.8z M911.8,453.9v-1.6h1.6v1.6H911.8z
469 - M911.8,455.5v-1.6h1.6v1.6H911.8z M913.5,457l-1.7,0.8v-2.3h1.6v1h-0.8l-0.3-0.7l0.5-0.3L913.5,457L913.5,457z M914.9,456.3
470 - l-1.4,0.7l-0.7-1.4l1.4-0.7L914.9,456.3z M916.3,455.6l-1.4,0.7l-0.7-1.4l1.4-0.7L916.3,455.6z M917.8,454.9l-1.4,0.7l-0.7-1.4
471 - l1.4-0.7L917.8,454.9z M919.2,454.1l-1.4,0.7l-0.7-1.4l1.4-0.7L919.2,454.1z M920.6,453.4l-1.4,0.7l-0.7-1.4l1.4-0.7L920.6,453.4z
472 - M922,452.7l-1.4,0.7l-0.7-1.4l1.4-0.7L922,452.7z M923.4,452l-1.4,0.7l-0.7-1.4l1.4-0.7L923.4,452z M924.9,451.3l-1.4,0.7
473 - l-0.7-1.4l1.4-0.7L924.9,451.3z M926.3,450.6l-1.4,0.7l-0.7-1.4l1.4-0.7L926.3,450.6z M927.7,449.9l-1.4,0.7l-0.7-1.4l1.4-0.7
474 - L927.7,449.9z M928.6,447.8l1.7,0.8l-2.6,1.3l-0.7-1.4l1.2-0.6l0.3,0.7l-0.3,0.7l-0.3-0.1L928.6,447.8L928.6,447.8z M927.2,447
475 - l1.4,0.7l-0.7,1.4l-1.4-0.7L927.2,447z M925.8,446.3l1.4,0.7l-0.7,1.4l-1.4-0.7L925.8,446.3z M924.3,445.6l1.4,0.7l-0.7,1.4
476 - l-1.4-0.7L924.3,445.6z M922.9,444.9l1.4,0.7l-0.7,1.4l-1.4-0.7L922.9,444.9z M921.5,444.2l1.4,0.7l-0.7,1.4l-1.4-0.7L921.5,444.2
477 - z M920.1,443.5l1.4,0.7l-0.7,1.4l-1.4-0.7L920.1,443.5z M918.7,442.8l1.4,0.7l-0.7,1.4l-1.4-0.7L918.7,442.8z M917.2,442.1
478 - l1.4,0.7l-0.7,1.4l-1.4-0.7L917.2,442.1z M915.8,441.4l1.4,0.7l-0.7,1.4l-1.4-0.7L915.8,441.4z M914.4,440.7l1.4,0.7l-0.7,1.4
479 - l-1.4-0.7L914.4,440.7z"/>
480 - </g>
481 -</g>
482 -<g>
483 - <defs>
484 - <rect id="SVGID_00000130609121672668402170000002014277360141959834_" x="10" y="-315.3" width="2473" height="1264"/>
485 - </defs>
486 - <clipPath id="SVGID_00000080906495298068389170000002540862521679494542_">
487 - <use xlink:href="#SVGID_00000130609121672668402170000002014277360141959834_" style="overflow:visible;"/>
488 - </clipPath>
489 - <g style="clip-path:url(#SVGID_00000080906495298068389170000002540862521679494542_);">
490 - <path class="st27" d="M508.8,99.3l7-1c7-1,20.8-3.1,55.2-4.1c34.3-1,89.1-1,143.8-1h328.5c54.8,0,109.5,0,144.7,7.7
491 - s50.9,23,65.7,37.3s28.6,27.9,35.5,34.6l6.9,6.7"/>
492 - </g>
493 -</g>
494 -<g>
495 - <defs>
496 - <rect id="SVGID_00000100356232179321915120000003128855251990665859_" x="10" y="-315.3" width="2473" height="1264"/>
497 - </defs>
498 - <clipPath id="SVGID_00000000205189414332796240000014182575778121501578_">
499 - <use xlink:href="#SVGID_00000100356232179321915120000003128855251990665859_" style="overflow:visible;"/>
500 - </clipPath>
501 - <g style="clip-path:url(#SVGID_00000000205189414332796240000014182575778121501578_);">
502 - <g>
503 - <defs>
504 - <rect id="SVGID_00000048489664338921055300000006549472999412979621_" x="10" y="-315.3" width="2473" height="1264"/>
505 - </defs>
506 - <clipPath id="SVGID_00000129170638479421875740000013358823573597412518_">
507 - <use xlink:href="#SVGID_00000048489664338921055300000006549472999412979621_" style="overflow:visible;"/>
508 - </clipPath>
509 - <g style="clip-path:url(#SVGID_00000129170638479421875740000013358823573597412518_);">
510 - <g>
511 - <defs>
512 -
513 - <rect id="SVGID_00000005264181436057707030000005903138745407607694_" x="501.7" y="91.3" transform="matrix(0.9891 -0.1469 0.1469 0.9891 -9.0449 75.9614)" width="15.8" height="15.8"/>
514 - </defs>
515 - <clipPath id="SVGID_00000053535797378313066300000016925176808506225837_">
516 - <use xlink:href="#SVGID_00000005264181436057707030000005903138745407607694_" style="overflow:visible;"/>
517 - </clipPath>
518 - <g style="clip-path:url(#SVGID_00000053535797378313066300000016925176808506225837_);">
519 - <polygon class="st3" points="501.8,100.4 518.6,105.9 516.3,90.2 "/>
520 - <path class="st3" d="M502.7,100.7l-0.5,0.3l-0.5-0.7l0.2-0.8l1.5,0.5l-0.5,1.5l-3-1l1.8-1.2L502.7,100.7L502.7,100.7z
521 - M504,99.8l-1.3,0.9l-0.9-1.3l1.3-0.9L504,99.8z M505.3,98.9l-1.3,0.9l-0.9-1.3l1.3-0.9L505.3,98.9z M506.6,97.9l-1.3,0.9
522 - l-0.9-1.3l1.3-0.9L506.6,97.9z M507.9,97l-1.3,0.9l-0.9-1.3l1.3-0.9L507.9,97z M509.2,96.1l-1.3,0.9l-0.9-1.3l1.3-0.9
523 - L509.2,96.1z M510.5,95.2l-1.3,0.9l-0.9-1.3l1.3-0.9L510.5,95.2z M511.8,94.3l-1.3,0.9l-0.9-1.3l1.3-0.9L511.8,94.3z
524 - M513.1,93.4l-1.3,0.9l-0.9-1.3l1.3-0.9L513.1,93.4z M514.4,92.5l-1.3,0.9l-0.9-1.3l1.3-0.9L514.4,92.5z M515.7,91.6l-1.3,0.9
525 - l-0.9-1.3l1.3-0.9L515.7,91.6z M515.6,90.6l0-0.3l0.8-0.1l0.5,0.7l-1.1,0.8l-0.9-1.3l2.1-1.5l0.2,1.6L515.6,90.6L515.6,90.6z
526 - M515.8,92.2l-0.2-1.6l1.6-0.2l0.2,1.6L515.8,92.2z M516,93.7l-0.2-1.6l1.6-0.2l0.2,1.6L516,93.7z M516.2,95.3l-0.2-1.6
527 - l1.6-0.2l0.2,1.6L516.2,95.3z M516.5,96.9l-0.2-1.6l1.6-0.2l0.2,1.6L516.5,96.9z M516.7,98.4l-0.2-1.6l1.6-0.2l0.2,1.6
528 - L516.7,98.4z M516.9,100l-0.2-1.6l1.6-0.2l0.2,1.6L516.9,100z M517.2,101.6l-0.2-1.6l1.6-0.2l0.2,1.6L517.2,101.6z
529 - M517.4,103.1l-0.2-1.6l1.6-0.2l0.2,1.6L517.4,103.1z M517.6,104.7l-0.2-1.6l1.6-0.2l0.2,1.6L517.6,104.7z M518.6,105l0.3,0.1
530 - l-0.2,0.8l-0.8,0.1l-0.2-1.3l1.6-0.2l0.4,2.6l-1.5-0.5L518.6,105z M517.1,104.6l1.5,0.5l-0.5,1.5l-1.5-0.5L517.1,104.6z
531 - M515.6,104.1l1.5,0.5l-0.5,1.5l-1.5-0.5L515.6,104.1z M514,103.6l1.5,0.5l-0.5,1.5l-1.5-0.5L514,103.6z M512.5,103.1l1.5,0.5
532 - l-0.5,1.5l-1.5-0.5L512.5,103.1z M511,102.6l1.5,0.5l-0.5,1.5l-1.5-0.5L511,102.6z M509.5,102.1l1.5,0.5l-0.5,1.5l-1.5-0.5
533 - L509.5,102.1z M508,101.6l1.5,0.5l-0.5,1.5l-1.5-0.5L508,101.6z M506.5,101.1l1.5,0.5l-0.5,1.5l-1.5-0.5L506.5,101.1z
534 - M505,100.6l1.5,0.5l-0.5,1.5l-1.5-0.5L505,100.6z M503.5,100.1l1.5,0.5l-0.5,1.5l-1.5-0.5L503.5,100.1z"/>
535 - </g>
536 - </g>
537 - </g>
538 - </g>
539 - </g>
540 -</g>
541 -<g>
542 - <defs>
543 - <rect id="SVGID_00000141415231417349126110000004347022815460784293_" x="10" y="-315.3" width="2473" height="1264"/>
544 - </defs>
545 - <clipPath id="SVGID_00000044173101564142372400000016877909101729436294_">
546 - <use xlink:href="#SVGID_00000141415231417349126110000004347022815460784293_" style="overflow:visible;"/>
547 - </clipPath>
548 - <g style="clip-path:url(#SVGID_00000044173101564142372400000016877909101729436294_);">
549 - <g>
550 - <defs>
551 - <rect id="SVGID_00000048473219809936292350000006331557118626080405_" x="10" y="-315.3" width="2473" height="1264"/>
552 - </defs>
553 - <clipPath id="SVGID_00000153674296733773009410000018181175898109783426_">
554 - <use xlink:href="#SVGID_00000048473219809936292350000006331557118626080405_" style="overflow:visible;"/>
555 - </clipPath>
556 - <g style="clip-path:url(#SVGID_00000153674296733773009410000018181175898109783426_);">
557 - <g>
558 - <defs>
559 -
560 - <rect id="SVGID_00000042724335089268839680000001285881850630468263_" x="1288.1" y="171.5" transform="matrix(0.6978 -0.7163 0.7163 0.6978 263.1707 982.5797)" width="15.8" height="15.8"/>
561 - </defs>
562 - <clipPath id="SVGID_00000046332282406793269810000013005250130014296731_">
563 - <use xlink:href="#SVGID_00000042724335089268839680000001285881850630468263_" style="overflow:visible;"/>
564 - </clipPath>
565 - <g style="clip-path:url(#SVGID_00000046332282406793269810000013005250130014296731_);">
566 - <polygon class="st3" points="1295.9,168.2 1301.7,185 1284.9,179.6 "/>
567 - <path class="st3" d="M1294.9,168.1l1.3-1.3l0.9,2.7l-1.5,0.5l-0.5-1.5l0.8-0.3l0.6,0.6l-0.4,0.4L1294.9,168.1L1294.9,168.1z
568 - M1293.8,169.2l1.1-1.1l1.1,1.1l-1.1,1.1L1293.8,169.2z M1292.7,170.4l1.1-1.1l1.1,1.1l-1.1,1.1L1292.7,170.4z M1291.6,171.5
569 - l1.1-1.1l1.1,1.1l-1.1,1.1L1291.6,171.5z M1290.5,172.6l1.1-1.1l1.1,1.1l-1.1,1.1L1290.5,172.6z M1289.4,173.8l1.1-1.1
570 - l1.1,1.1l-1.1,1.1L1289.4,173.8z M1288.3,174.9l1.1-1.1l1.1,1.1l-1.1,1.1L1288.3,174.9z M1287.2,176l1.1-1.1l1.1,1.1l-1.1,1.1
571 - L1287.2,176z M1286.1,177.1l1.1-1.1l1.1,1.1l-1.1,1.1L1286.1,177.1z M1285,178.3l1.1-1.1l1.1,1.1l-1.1,1.1L1285,178.3z
572 - M1285.1,180.5l-1.8-0.6l1.6-1.6l1.1,1.1l-0.7,0.7l-0.6-0.6l0.2-0.8l0.5,0.2L1285.1,180.5L1285.1,180.5z M1286.6,181l-1.5-0.5
573 - l0.5-1.5l1.5,0.5L1286.6,181z M1288.1,181.4l-1.5-0.5l0.5-1.5l1.5,0.5L1288.1,181.4z M1289.7,181.9l-1.5-0.5l0.5-1.5l1.5,0.5
574 - L1289.7,181.9z M1291.2,182.4l-1.5-0.5l0.5-1.5l1.5,0.5L1291.2,182.4z M1292.7,182.9l-1.5-0.5l0.5-1.5l1.5,0.5L1292.7,182.9z
575 - M1294.2,183.4l-1.5-0.5l0.5-1.5l1.5,0.5L1294.2,183.4z M1295.7,183.8l-1.5-0.5l0.5-1.5l1.5,0.5L1295.7,183.8z M1297.2,184.3
576 - l-1.5-0.5l0.5-1.5l1.5,0.5L1297.2,184.3z M1298.7,184.8l-1.5-0.5l0.5-1.5l1.5,0.5L1298.7,184.8z M1300.2,185.3l-1.5-0.5
577 - l0.5-1.5l1.5,0.5L1300.2,185.3z M1302.4,184.4l0.6,1.8l-2.8-0.9l0.5-1.5l1.2,0.4l-0.2,0.8l-0.8,0.3l-0.1-0.3L1302.4,184.4
578 - L1302.4,184.4z M1301.8,182.9l0.5,1.5l-1.5,0.5l-0.5-1.5L1301.8,182.9z M1301.3,181.4l0.5,1.5l-1.5,0.5l-0.5-1.5L1301.3,181.4
579 - z M1300.8,179.9l0.5,1.5l-1.5,0.5l-0.5-1.5L1300.8,179.9z M1300.3,178.4l0.5,1.5l-1.5,0.5l-0.5-1.5L1300.3,178.4z
580 - M1299.8,176.9l0.5,1.5l-1.5,0.5l-0.5-1.5L1299.8,176.9z M1299.2,175.4l0.5,1.5l-1.5,0.5l-0.5-1.5L1299.2,175.4z
581 - M1298.7,173.9l0.5,1.5l-1.5,0.5l-0.5-1.5L1298.7,173.9z M1298.2,172.4l0.5,1.5l-1.5,0.5l-0.5-1.5L1298.2,172.4z
582 - M1297.7,170.9l0.5,1.5l-1.5,0.5l-0.5-1.5L1297.7,170.9z M1297.2,169.4l0.5,1.5l-1.5,0.5l-0.5-1.5L1297.2,169.4z"/>
583 - </g>
584 - </g>
585 - </g>
586 - </g>
587 - </g>
588 -</g>
589 -<g>
590 - <defs>
591 - <rect id="SVGID_00000132057561414629851790000009196947999050764970_" x="10" y="-315.3" width="2473" height="1264"/>
592 - </defs>
593 - <clipPath id="SVGID_00000106147175948805499000000001804287911640596097_">
594 - <use xlink:href="#SVGID_00000132057561414629851790000009196947999050764970_" style="overflow:visible;"/>
595 - </clipPath>
596 - <g style="clip-path:url(#SVGID_00000106147175948805499000000001804287911640596097_);">
597 - <path class="st27" d="M837.3,232.8l6.9-0.8c6.9-0.8,20.8-2.5,55.1-3.4c34.3-0.8,89.1-0.8,143.8-0.8c54.7,0,109.5,0,141.1,0.1
598 - s40,0.2,47.1,0.4c7.1,0.1,12.9,0.2,15.8,0.3l2.9,0.1"/>
599 - </g>
600 -</g>
601 -<g>
602 - <defs>
603 - <rect id="SVGID_00000099657363769161996980000005152130896269652926_" x="10" y="-315.3" width="2473" height="1264"/>
604 - </defs>
605 - <clipPath id="SVGID_00000069380115010529667450000004985023639827414155_">
606 - <use xlink:href="#SVGID_00000099657363769161996980000005152130896269652926_" style="overflow:visible;"/>
607 - </clipPath>
608 - <g style="clip-path:url(#SVGID_00000069380115010529667450000004985023639827414155_);">
609 - <g>
610 - <defs>
611 - <rect id="SVGID_00000036932012937151335440000005605535174306996120_" x="10" y="-315.3" width="2473" height="1264"/>
612 - </defs>
613 - <clipPath id="SVGID_00000114775462026487132210000004691926687091032992_">
614 - <use xlink:href="#SVGID_00000036932012937151335440000005605535174306996120_" style="overflow:visible;"/>
615 - </clipPath>
616 - <g style="clip-path:url(#SVGID_00000114775462026487132210000004691926687091032992_);">
617 - <g>
618 - <defs>
619 -
620 - <rect id="SVGID_00000096763837226321560440000004235390868712881812_" x="830.2" y="224.8" transform="matrix(0.9928 -0.1198 0.1198 0.9928 -21.8434 102.0734)" width="15.8" height="15.8"/>
621 - </defs>
622 - <clipPath id="SVGID_00000035505589384069763780000017226163769440666791_">
623 - <use xlink:href="#SVGID_00000096763837226321560440000004235390868712881812_" style="overflow:visible;"/>
624 - </clipPath>
625 - <g style="clip-path:url(#SVGID_00000035505589384069763780000017226163769440666791_);">
626 - <polygon class="st3" points="830.2,233.7 846.9,239.6 845,223.9 "/>
627 - <path class="st3" d="M831.2,234l-0.5,0.3l-0.4-0.7l0.3-0.8l1.5,0.5l-0.5,1.5l-3-1.1l1.8-1.2L831.2,234L831.2,234z
628 - M832.5,233.1l-1.3,0.9l-0.9-1.3l1.3-0.9L832.5,233.1z M833.8,232.3l-1.3,0.9l-0.9-1.3l1.3-0.9L833.8,232.3z M835.1,231.4
629 - l-1.3,0.9l-0.9-1.3l1.3-0.9L835.1,231.4z M836.4,230.5l-1.3,0.9l-0.9-1.3l1.3-0.9L836.4,230.5z M837.8,229.7l-1.3,0.9
630 - l-0.9-1.3l1.3-0.9L837.8,229.7z M839.1,228.8l-1.3,0.9l-0.9-1.3l1.3-0.9L839.1,228.8z M840.4,227.9l-1.3,0.9l-0.9-1.3l1.3-0.9
631 - L840.4,227.9z M841.7,227.1l-1.3,0.9l-0.9-1.3l1.3-0.9L841.7,227.1z M843,226.2l-1.3,0.9l-0.9-1.3l1.3-0.9L843,226.2z
632 - M844.4,225.3l-1.3,0.9l-0.9-1.3l1.3-0.9L844.4,225.3z M844.3,224.3l0-0.3l0.8-0.1l0.4,0.7l-1.1,0.7l-0.9-1.3l2.2-1.4l0.2,1.6
633 - L844.3,224.3L844.3,224.3z M844.4,225.9l-0.2-1.6l1.6-0.2l0.2,1.6L844.4,225.9z M844.6,227.5l-0.2-1.6l1.6-0.2l0.2,1.6
634 - L844.6,227.5z M844.8,229l-0.2-1.6l1.6-0.2l0.2,1.6L844.8,229z M845,230.6l-0.2-1.6l1.6-0.2l0.2,1.6L845,230.6z M845.2,232.2
635 - l-0.2-1.6l1.6-0.2l0.2,1.6L845.2,232.2z M845.4,233.7l-0.2-1.6l1.6-0.2l0.2,1.6L845.4,233.7z M845.6,235.3l-0.2-1.6l1.6-0.2
636 - l0.2,1.6L845.6,235.3z M845.8,236.9l-0.2-1.6l1.6-0.2l0.2,1.6L845.8,236.9z M846,238.4l-0.2-1.6l1.6-0.2l0.2,1.6L846,238.4z
637 - M846.9,238.8l0.3,0.1l-0.3,0.8l-0.8,0.1l-0.2-1.3l1.6-0.2l0.3,2.6l-1.5-0.5L846.9,238.8L846.9,238.8z M845.4,238.3l1.5,0.5
638 - l-0.5,1.5l-1.5-0.5L845.4,238.3z M843.9,237.7l1.5,0.5l-0.5,1.5l-1.5-0.5L843.9,237.7z M842.4,237.2l1.5,0.5l-0.5,1.5
639 - l-1.5-0.5L842.4,237.2z M840.9,236.7l1.5,0.5l-0.5,1.5l-1.5-0.5L840.9,236.7z M839.5,236.1l1.5,0.5l-0.5,1.5l-1.5-0.5
640 - L839.5,236.1z M838,235.6l1.5,0.5l-0.5,1.5l-1.5-0.5L838,235.6z M836.5,235.1l1.5,0.5l-0.5,1.5l-1.5-0.5L836.5,235.1z
641 - M835,234.6l1.5,0.5l-0.5,1.5l-1.5-0.5L835,234.6z M833.5,234l1.5,0.5l-0.5,1.5l-1.5-0.5L833.5,234z M832,233.5l1.5,0.5
642 - l-0.5,1.5l-1.5-0.5L832,233.5z"/>
643 - </g>
644 - </g>
645 - </g>
646 - </g>
647 - </g>
648 -</g>
649 -<g>
650 - <defs>
651 - <rect id="SVGID_00000021829021536836738180000016492556188216618940_" x="10" y="-315.3" width="2473" height="1264"/>
652 - </defs>
653 - <clipPath id="SVGID_00000029747494173536645850000016560023481934200726_">
654 - <use xlink:href="#SVGID_00000021829021536836738180000016492556188216618940_" style="overflow:visible;"/>
655 - </clipPath>
656 - <g style="clip-path:url(#SVGID_00000029747494173536645850000016560023481934200726_);">
657 - <g>
658 - <defs>
659 - <rect id="SVGID_00000062186868041705309380000015453062764582635435_" x="10" y="-315.3" width="2473" height="1264"/>
660 - </defs>
661 - <clipPath id="SVGID_00000049904433297589781460000003473368813938909852_">
662 - <use xlink:href="#SVGID_00000062186868041705309380000015453062764582635435_" style="overflow:visible;"/>
663 - </clipPath>
664 - <g style="clip-path:url(#SVGID_00000049904433297589781460000003473368813938909852_);">
665 - <g>
666 - <defs>
667 -
668 - <rect id="SVGID_00000031191136678144010940000012075629018954224812_" x="1242.1" y="220.7" transform="matrix(1.989543e-02 -0.9998 0.9998 1.989543e-02 996.5935 1473.8743)" width="15.8" height="15.8"/>
669 - </defs>
670 - <clipPath id="SVGID_00000110431934226839133410000010808372942951483553_">
671 - <use xlink:href="#SVGID_00000031191136678144010940000012075629018954224812_" style="overflow:visible;"/>
672 - </clipPath>
673 - <g style="clip-path:url(#SVGID_00000110431934226839133410000010808372942951483553_);">
674 - <polygon class="st3" points="1242.2,220.5 1257.9,228.8 1241.9,236.4 "/>
675 - <path class="st3" d="M1241.4,221.1l0-1.9l2.5,1.3l-0.7,1.4l-1.4-0.7l0.4-0.7l0.8,0v0.6L1241.4,221.1L1241.4,221.1z
676 - M1241.4,222.7l0-1.6l1.6,0l0,1.6L1241.4,222.7z M1241.4,224.3l0-1.6l1.6,0l0,1.6L1241.4,224.3z M1241.4,225.8l0-1.6l1.6,0
677 - l0,1.6L1241.4,225.8z M1241.3,227.4l0-1.6l1.6,0l0,1.6L1241.3,227.4z M1241.3,229l0-1.6l1.6,0l0,1.6L1241.3,229z
678 - M1241.3,230.6l0-1.6l1.6,0l0,1.6L1241.3,230.6z M1241.2,232.2l0-1.6l1.6,0l0,1.6L1241.2,232.2z M1241.2,233.7l0-1.6l1.6,0
679 - l0,1.6L1241.2,233.7z M1241.2,235.3l0-1.6l1.6,0l0,1.6L1241.2,235.3z M1242.8,236.8l-1.7,0.8l0.1-2.3l1.6,0l0,1l-0.8,0
680 - l-0.3-0.7l0.5-0.2L1242.8,236.8L1242.8,236.8z M1244.2,236.1l-1.4,0.7l-0.7-1.4l1.4-0.7L1244.2,236.1z M1245.7,235.5l-1.4,0.7
681 - l-0.7-1.4l1.4-0.7L1245.7,235.5z M1247.1,234.8l-1.4,0.7l-0.7-1.4l1.4-0.7L1247.1,234.8z M1248.5,234.1l-1.4,0.7l-0.7-1.4
682 - l1.4-0.7L1248.5,234.1z M1250,233.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1250,233.4z M1251.4,232.7l-1.4,0.7l-0.7-1.4l1.4-0.7
683 - L1251.4,232.7z M1252.8,232.1l-1.4,0.7l-0.7-1.4l1.4-0.7L1252.8,232.1z M1254.3,231.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1254.3,231.4
684 - z M1255.7,230.7l-1.4,0.7l-0.7-1.4l1.4-0.7L1255.7,230.7z M1257.1,230l-1.4,0.7l-0.7-1.4l1.4-0.7L1257.1,230z M1258.1,227.9
685 - l1.7,0.9l-2.6,1.2l-0.7-1.4l1.2-0.6l0.3,0.7l-0.4,0.7l-0.2-0.1L1258.1,227.9L1258.1,227.9z M1256.7,227.2l1.4,0.7l-0.7,1.4
686 - l-1.4-0.7L1256.7,227.2z M1255.3,226.4l1.4,0.7l-0.7,1.4l-1.4-0.7L1255.3,226.4z M1253.9,225.7l1.4,0.7l-0.7,1.4l-1.4-0.7
687 - L1253.9,225.7z M1252.5,225l1.4,0.7l-0.7,1.4l-1.4-0.7L1252.5,225z M1251.1,224.2l1.4,0.7l-0.7,1.4l-1.4-0.7L1251.1,224.2z
688 - M1249.7,223.5l1.4,0.7l-0.7,1.4l-1.4-0.7L1249.7,223.5z M1248.3,222.7l1.4,0.7l-0.7,1.4l-1.4-0.7L1248.3,222.7z M1246.9,222
689 - l1.4,0.7l-0.7,1.4l-1.4-0.7L1246.9,222z M1245.5,221.3l1.4,0.7l-0.7,1.4l-1.4-0.7L1245.5,221.3z M1244.1,220.5l1.4,0.7
690 - l-0.7,1.4l-1.4-0.7L1244.1,220.5z"/>
691 - </g>
692 - </g>
693 - </g>
694 - </g>
695 - </g>
696 -</g>
697 -<g>
698 - <defs>
699 - <rect id="SVGID_00000183955303964032033650000006533571448350718866_" x="10" y="-315.3" width="2473" height="1264"/>
700 - </defs>
701 - <clipPath id="SVGID_00000118384531667720095360000002748900312211283886_">
702 - <use xlink:href="#SVGID_00000183955303964032033650000006533571448350718866_" style="overflow:visible;"/>
703 - </clipPath>
704 - <g style="clip-path:url(#SVGID_00000118384531667720095360000002748900312211283886_);">
705 - <path class="st27" d="M1165.8,448.6h6.9c6.9,0,20.8,0,36.5-13.8s33.2-41.3,50-67.8c16.8-26.4,32.9-51.8,41-64.4l8.1-12.7"/>
706 - </g>
707 -</g>
708 -<g>
709 - <defs>
710 - <rect id="SVGID_00000091711202723249612370000013067476220107639459_" x="1158.7" y="440.7" width="15.8" height="15.8"/>
711 - </defs>
712 - <clipPath id="SVGID_00000167365524207122294160000010205490912526147200_">
713 - <use xlink:href="#SVGID_00000091711202723249612370000013067476220107639459_" style="overflow:visible;"/>
714 - </clipPath>
715 - <g style="clip-path:url(#SVGID_00000167365524207122294160000010205490912526147200_);">
716 - <polygon class="st3" points="1158.7,448.6 1174.6,456.6 1174.6,440.7 "/>
717 - <path class="st3" d="M1159.6,449.1l-0.5,0.3l-0.3-0.7l0.3-0.7l1.4,0.7l-0.7,1.4l-2.8-1.4l1.9-1L1159.6,449.1L1159.6,449.1z
718 - M1161,448.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1161,448.4z M1162.4,447.7l-1.4,0.7l-0.7-1.4l1.4-0.7L1162.4,447.7z M1163.9,447l-1.4,0.7
719 - l-0.7-1.4l1.4-0.7L1163.9,447z M1165.3,446.3l-1.4,0.7l-0.7-1.4l1.4-0.7L1165.3,446.3z M1166.7,445.6l-1.4,0.7l-0.7-1.4l1.4-0.7
720 - L1166.7,445.6z M1168.1,444.9l-1.4,0.7l-0.7-1.4l1.4-0.7L1168.1,444.9z M1169.5,444.1l-1.4,0.7l-0.7-1.4l1.4-0.7L1169.5,444.1z
721 - M1171,443.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1171,443.4z M1172.4,442.7l-1.4,0.7l-0.7-1.4l1.4-0.7L1172.4,442.7z M1173.8,442l-1.4,0.7
722 - l-0.7-1.4l1.4-0.7L1173.8,442z M1173.8,441v-0.3h0.8l0.3,0.7l-1.2,0.6l-0.7-1.4l2.3-1.1v1.6L1173.8,441L1173.8,441z M1173.8,442.6
723 - V441h1.6v1.6H1173.8z M1173.8,444.2v-1.6h1.6v1.6H1173.8z M1173.8,445.8v-1.6h1.6v1.6H1173.8z M1173.8,447.3v-1.6h1.6v1.6H1173.8z
724 - M1173.8,448.9v-1.6h1.6v1.6H1173.8z M1173.8,450.5v-1.6h1.6v1.6H1173.8z M1173.8,452.1v-1.6h1.6v1.6H1173.8z M1173.8,453.6v-1.6
725 - h1.6v1.6H1173.8z M1173.8,455.2v-1.6h1.6v1.6H1173.8z M1174.7,455.7l0.3,0.1l-0.3,0.7h-0.8v-1.3h1.6v2.6l-1.4-0.7L1174.7,455.7
726 - L1174.7,455.7z M1173.3,455l1.4,0.7l-0.7,1.4l-1.4-0.7L1173.3,455z M1171.9,454.3l1.4,0.7l-0.7,1.4l-1.4-0.7L1171.9,454.3z
727 - M1170.4,453.6l1.4,0.7l-0.7,1.4l-1.4-0.7L1170.4,453.6z M1169,452.8l1.4,0.7l-0.7,1.4l-1.4-0.7L1169,452.8z M1167.6,452.1
728 - l1.4,0.7l-0.7,1.4l-1.4-0.7L1167.6,452.1z M1166.2,451.4l1.4,0.7l-0.7,1.4l-1.4-0.7L1166.2,451.4z M1164.8,450.7l1.4,0.7l-0.7,1.4
729 - l-1.4-0.7L1164.8,450.7z M1163.3,450l1.4,0.7l-0.7,1.4l-1.4-0.7L1163.3,450z M1161.9,449.3l1.4,0.7l-0.7,1.4l-1.4-0.7
730 - L1161.9,449.3z M1160.5,448.6l1.4,0.7l-0.7,1.4l-1.4-0.7L1160.5,448.6z"/>
731 - </g>
732 -</g>
733 -<g>
734 - <defs>
735 - <rect id="SVGID_00000167384701048989971760000000073175456722057131_" x="10" y="-315.3" width="2473" height="1264"/>
736 - </defs>
737 - <clipPath id="SVGID_00000121981081522528985380000003895317323019368348_">
738 - <use xlink:href="#SVGID_00000167384701048989971760000000073175456722057131_" style="overflow:visible;"/>
739 - </clipPath>
740 - <g style="clip-path:url(#SVGID_00000121981081522528985380000003895317323019368348_);">
741 - <g>
742 - <defs>
743 - <rect id="SVGID_00000023999592618231684190000004269945565907780485_" x="10" y="-315.3" width="2473" height="1264"/>
744 - </defs>
745 - <clipPath id="SVGID_00000075148404719187371980000011770155237397649295_">
746 - <use xlink:href="#SVGID_00000023999592618231684190000004269945565907780485_" style="overflow:visible;"/>
747 - </clipPath>
748 - <g style="clip-path:url(#SVGID_00000075148404719187371980000011770155237397649295_);">
749 - <g>
750 - <defs>
751 -
752 - <rect id="SVGID_00000099640463598947540910000008440417572511635099_" x="1300.3" y="282.1" transform="matrix(0.5366 -0.8439 0.8439 0.5366 361.5684 1238.3348)" width="15.8" height="15.8"/>
753 - </defs>
754 - <clipPath id="SVGID_00000179604797795163600640000001617902263014635936_">
755 - <use xlink:href="#SVGID_00000099640463598947540910000008440417572511635099_" style="overflow:visible;"/>
756 - </clipPath>
757 - <g style="clip-path:url(#SVGID_00000179604797795163600640000001617902263014635936_);">
758 - <polygon class="st3" points="1297.3,292.5 1312.5,283.4 1310.7,301 "/>
759 - <path class="st3" d="M1297.4,293.5l-1.6-1l2.5-1.5l0.8,1.4l-1.4,0.8l-0.4-0.7l0.4-0.7l0.5,0.3L1297.4,293.5L1297.4,293.5z
760 - M1298.8,294.3l-1.3-0.9l0.8-1.3l1.3,0.9L1298.8,294.3z M1300.1,295.2l-1.3-0.9l0.8-1.3l1.3,0.9L1300.1,295.2z M1301.4,296
761 - l-1.3-0.9l0.8-1.3l1.3,0.9L1301.4,296z M1302.8,296.9l-1.3-0.9l0.8-1.3l1.3,0.9L1302.8,296.9z M1304.1,297.7l-1.3-0.9l0.8-1.3
762 - l1.3,0.9L1304.1,297.7z M1305.4,298.6l-1.3-0.9l0.8-1.3l1.3,0.9L1305.4,298.6z M1306.8,299.4l-1.3-0.9l0.8-1.3l1.3,0.9
763 - L1306.8,299.4z M1308.1,300.3l-1.3-0.9l0.8-1.3l1.3,0.9L1308.1,300.3z M1309.5,301.1l-1.3-0.9l0.8-1.3l1.3,0.9L1309.5,301.1z
764 - M1311.6,300.5l-0.2,1.8l-1.9-1.2l0.8-1.3l0.8,0.5l-0.4,0.7l-0.8-0.1l0.1-0.6L1311.6,300.5L1311.6,300.5z M1311.8,298.9
765 - l-0.2,1.6l-1.6-0.2l0.2-1.6L1311.8,298.9z M1311.9,297.3l-0.2,1.6l-1.6-0.2l0.2-1.6L1311.9,297.3z M1312.1,295.8l-0.2,1.6
766 - l-1.6-0.2l0.2-1.6L1312.1,295.8z M1312.2,294.2l-0.2,1.6l-1.6-0.2l0.2-1.6L1312.2,294.2z M1312.4,292.6l-0.2,1.6l-1.6-0.2
767 - l0.2-1.6L1312.4,292.6z M1312.6,291l-0.2,1.6l-1.6-0.2l0.2-1.6L1312.6,291z M1312.7,289.5l-0.2,1.6l-1.6-0.2l0.2-1.6
768 - L1312.7,289.5z M1312.9,287.9l-0.2,1.6l-1.6-0.2l0.2-1.6L1312.9,287.9z M1313,286.3l-0.2,1.6l-1.6-0.2l0.2-1.6L1313,286.3z
769 - M1313.2,284.7l-0.2,1.6l-1.6-0.2l0.2-1.6L1313.2,284.7z M1311.9,282.8l1.6-1l-0.3,2.9l-1.6-0.2l0.1-1.3l0.8,0.1l0.4,0.7
770 - l-0.2,0.1L1311.9,282.8L1311.9,282.8z M1310.5,283.6l1.4-0.8l0.8,1.4l-1.4,0.8L1310.5,283.6z M1309.2,284.4l1.4-0.8l0.8,1.4
771 - l-1.4,0.8L1309.2,284.4z M1307.8,285.3l1.4-0.8l0.8,1.4l-1.4,0.8L1307.8,285.3z M1306.5,286.1l1.4-0.8l0.8,1.4l-1.4,0.8
772 - L1306.5,286.1z M1305.1,286.9l1.4-0.8l0.8,1.4l-1.4,0.8L1305.1,286.9z M1303.7,287.7l1.4-0.8l0.8,1.4l-1.4,0.8L1303.7,287.7z
773 - M1302.4,288.5l1.4-0.8l0.8,1.4l-1.4,0.8L1302.4,288.5z M1301,289.4l1.4-0.8l0.8,1.4l-1.4,0.8L1301,289.4z M1299.7,290.2
774 - l1.4-0.8l0.8,1.4l-1.4,0.8L1299.7,290.2z M1298.3,291l1.4-0.8l0.8,1.4l-1.4,0.8L1298.3,291z"/>
775 - </g>
776 - </g>
777 - </g>
778 - </g>
779 - </g>
780 -</g>
781 -<g>
782 - <defs>
783 - <rect id="SVGID_00000080900766610112941480000017788023775162236586_" x="10" y="-315.3" width="2473" height="1264"/>
784 - </defs>
785 - <clipPath id="SVGID_00000089539490752864619270000007764174044062086284_">
786 - <use xlink:href="#SVGID_00000080900766610112941480000017788023775162236586_" style="overflow:visible;"/>
787 - </clipPath>
788 - <g style="clip-path:url(#SVGID_00000089539490752864619270000007764174044062086284_);">
789 - <path class="st3" d="M1570.6,226.8h3.5v2h-3.5V226.8z M1562.6,226.8h3.7v2h-3.7V226.8z M1554.6,226.8h3.9v2h-3.9V226.8z
790 - M1546.6,226.8h4.2v2h-4.2V226.8z M1539.1,226.8h3.7v2h-3.7V226.8z M1530.8,226.8h4.3v2h-4.3V226.8z M1523.2,226.8h3.7v2h-3.7
791 - V226.8z M1515.2,226.8h4.1v2h-4.1V226.8z M1506.9,226.8h4.1v2h-4.1V226.8z M1499.1,226.8l3.9,0v2l-3.9,0L1499.1,226.8
792 - L1499.1,226.8z M1491.1,226.9l4,0v2l-4,0L1491.1,226.9L1491.1,226.9z M1483,227h1.2l1.9,0h1l0,2h-1l-1.9,0h-1.2L1483,227z
793 - M1474.8,227.1l4.1-0.1l0,2l-4.1,0.1L1474.8,227.1z M1466.8,227.2l3.9-0.1l0,2l-3.9,0.1L1466.8,227.2z M1459.2,227.3l3.9-0.1l0,2
794 - l-3.9,0.1L1459.2,227.3z M1451.3,227.5l3.8-0.1l0,2l-3.8,0.1L1451.3,227.5z M1443.4,227.6h0.2l3.5-0.1l0,2l-3.5,0.1h-0.2
795 - L1443.4,227.6z M1435.5,227.8l4-0.1l0,2l-4,0.1L1435.5,227.8z"/>
796 - </g>
797 -</g>
798 -<g>
799 - <defs>
800 - <rect id="SVGID_00000055692140626774951560000018358176439156532106_" x="1567.2" y="219.9" width="15.8" height="15.8"/>
801 - </defs>
802 - <clipPath id="SVGID_00000031925080658095673190000002656465933969291428_">
803 - <use xlink:href="#SVGID_00000055692140626774951560000018358176439156532106_" style="overflow:visible;"/>
804 - </clipPath>
805 - <g style="clip-path:url(#SVGID_00000031925080658095673190000002656465933969291428_);">
806 - <polygon class="st3" points="1567.2,219.9 1583.1,227.8 1567.2,235.7 "/>
807 - <path class="st3" d="M1566.4,220.4v-1.9l2.6,1.3l-0.7,1.4l-1.4-0.7l0.3-0.7h0.8v0.6L1566.4,220.4L1566.4,220.4z M1566.4,222v-1.6
808 - h1.6v1.6H1566.4z M1566.4,223.6V222h1.6v1.6H1566.4z M1566.4,225.2v-1.6h1.6v1.6H1566.4z M1566.4,226.8v-1.6h1.6v1.6H1566.4z
809 - M1566.4,228.3v-1.6h1.6v1.6H1566.4z M1566.4,229.9v-1.6h1.6v1.6H1566.4z M1566.4,231.5v-1.6h1.6v1.6H1566.4z M1566.4,233.1v-1.6
810 - h1.6v1.6H1566.4z M1566.4,234.7v-1.6h1.6v1.6H1566.4z M1568.1,236.1l-1.7,0.8v-2.3h1.6v1h-0.8l-0.3-0.7l0.5-0.3L1568.1,236.1
811 - L1568.1,236.1z M1569.5,235.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1569.5,235.4z M1570.9,234.7l-1.4,0.7l-0.7-1.4l1.4-0.7L1570.9,234.7z
812 - M1572.4,234l-1.4,0.7l-0.7-1.4l1.4-0.7L1572.4,234z M1573.8,233.3l-1.4,0.7l-0.7-1.4l1.4-0.7L1573.8,233.3z M1575.2,232.6
813 - l-1.4,0.7l-0.7-1.4l1.4-0.7L1575.2,232.6z M1576.6,231.9l-1.4,0.7l-0.7-1.4l1.4-0.7L1576.6,231.9z M1578,231.1l-1.4,0.7l-0.7-1.4
814 - l1.4-0.7L1578,231.1z M1579.5,230.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1579.5,230.4z M1580.9,229.7l-1.4,0.7l-0.7-1.4l1.4-0.7
815 - L1580.9,229.7z M1582.3,229l-1.4,0.7l-0.7-1.4l1.4-0.7L1582.3,229z M1583.2,226.9l1.7,0.8l-2.6,1.3l-0.7-1.4l1.2-0.6l0.3,0.7
816 - l-0.3,0.7l-0.3-0.1L1583.2,226.9L1583.2,226.9z M1581.8,226.2l1.4,0.7l-0.7,1.4l-1.4-0.7L1581.8,226.2z M1580.4,225.5l1.4,0.7
817 - l-0.7,1.4l-1.4-0.7L1580.4,225.5z M1578.9,224.8l1.4,0.7l-0.7,1.4l-1.4-0.7L1578.9,224.8z M1577.5,224l1.4,0.7l-0.7,1.4l-1.4-0.7
818 - L1577.5,224z M1576.1,223.3l1.4,0.7l-0.7,1.4l-1.4-0.7L1576.1,223.3z M1574.7,222.6l1.4,0.7l-0.7,1.4l-1.4-0.7L1574.7,222.6z
819 - M1573.3,221.9l1.4,0.7l-0.7,1.4l-1.4-0.7L1573.3,221.9z M1571.8,221.2l1.4,0.7l-0.7,1.4l-1.4-0.7L1571.8,221.2z M1570.4,220.5
820 - l1.4,0.7l-0.7,1.4l-1.4-0.7L1570.4,220.5z M1569,219.8l1.4,0.7l-0.7,1.4l-1.4-0.7L1569,219.8z"/>
821 - </g>
822 -</g>
823 -<g>
824 - <defs>
825 - <rect id="SVGID_00000082328905178908513470000016828721385536177339_" x="10" y="-315.3" width="2473" height="1264"/>
826 - </defs>
827 - <clipPath id="SVGID_00000012459626582397514060000009524383776792149662_">
828 - <use xlink:href="#SVGID_00000082328905178908513470000016828721385536177339_" style="overflow:visible;"/>
829 - </clipPath>
830 - <g style="clip-path:url(#SVGID_00000012459626582397514060000009524383776792149662_);">
831 - <path class="st27" d="M1996.1,227.8h83.2"/>
832 - </g>
833 -</g>
834 -<g>
835 - <defs>
836 - <rect id="SVGID_00000000204867960409065840000003490529602289955221_" x="1988.9" y="219.9" width="15.8" height="15.8"/>
837 - </defs>
838 - <clipPath id="SVGID_00000052104183626941848480000007149735530026157697_">
839 - <use xlink:href="#SVGID_00000000204867960409065840000003490529602289955221_" style="overflow:visible;"/>
840 - </clipPath>
841 - <g style="clip-path:url(#SVGID_00000052104183626941848480000007149735530026157697_);">
842 - <polygon class="st3" points="1988.9,227.8 2004.8,235.7 2004.8,219.9 "/>
843 - <path class="st3" d="M1989.8,228.2l-0.5,0.3l-0.3-0.7l0.3-0.7l1.4,0.7l-0.7,1.4l-2.8-1.4l1.9-1L1989.8,228.2L1989.8,228.2z
844 - M1991.2,227.5l-1.4,0.7l-0.7-1.4l1.4-0.7L1991.2,227.5z M1992.7,226.8l-1.4,0.7l-0.7-1.4l1.4-0.7L1992.7,226.8z M1994.1,226.1
845 - l-1.4,0.7l-0.7-1.4l1.4-0.7L1994.1,226.1z M1995.5,225.4l-1.4,0.7l-0.7-1.4l1.4-0.7L1995.5,225.4z M1996.9,224.7l-1.4,0.7
846 - l-0.7-1.4l1.4-0.7L1996.9,224.7z M1998.3,224l-1.4,0.7l-0.7-1.4l1.4-0.7L1998.3,224z M1999.8,223.3l-1.4,0.7l-0.7-1.4l1.4-0.7
847 - L1999.8,223.3z M2001.2,222.6l-1.4,0.7l-0.7-1.4l1.4-0.7L2001.2,222.6z M2002.6,221.8l-1.4,0.7l-0.7-1.4l1.4-0.7L2002.6,221.8z
848 - M2004,221.1l-1.4,0.7l-0.7-1.4l1.4-0.7L2004,221.1z M2004,220.1v-0.3h0.8l0.3,0.7l-1.2,0.6l-0.7-1.4l2.3-1.1v1.6L2004,220.1
849 - L2004,220.1z M2004,221.7v-1.6h1.6v1.6H2004z M2004,223.3v-1.6h1.6v1.6H2004z M2004,224.9v-1.6h1.6v1.6H2004z M2004,226.5v-1.6
850 - h1.6v1.6H2004z M2004,228v-1.6h1.6v1.6H2004z M2004,229.6V228h1.6v1.6H2004z M2004,231.2v-1.6h1.6v1.6H2004z M2004,232.8v-1.6h1.6
851 - v1.6H2004z M2004,234.4v-1.6h1.6v1.6H2004z M2004.9,234.8l0.3,0.1l-0.3,0.7h-0.8v-1.3h1.6v2.6l-1.4-0.7L2004.9,234.8L2004.9,234.8
852 - z M2003.5,234.1l1.4,0.7l-0.7,1.4l-1.4-0.7L2003.5,234.1z M2002.1,233.4l1.4,0.7l-0.7,1.4l-1.4-0.7L2002.1,233.4z M2000.7,232.7
853 - l1.4,0.7l-0.7,1.4l-1.4-0.7L2000.7,232.7z M1999.2,232l1.4,0.7l-0.7,1.4l-1.4-0.7L1999.2,232z M1997.8,231.3l1.4,0.7l-0.7,1.4
854 - l-1.4-0.7L1997.8,231.3z M1996.4,230.6l1.4,0.7l-0.7,1.4l-1.4-0.7L1996.4,230.6z M1995,229.8l1.4,0.7l-0.7,1.4l-1.4-0.7
855 - L1995,229.8z M1993.6,229.1l1.4,0.7l-0.7,1.4l-1.4-0.7L1993.6,229.1z M1992.1,228.4l1.4,0.7l-0.7,1.4l-1.4-0.7L1992.1,228.4z
856 - M1990.7,227.7l1.4,0.7l-0.7,1.4l-1.4-0.7L1990.7,227.7z"/>
857 - </g>
858 -</g>
859 -<g>
860 - <defs>
861 - <rect id="SVGID_00000096037155027899726430000003377672684665991553_" x="2071.3" y="219.9" width="15.8" height="15.8"/>
862 - </defs>
863 - <clipPath id="SVGID_00000004509549875243981780000017806978581699248034_">
864 - <use xlink:href="#SVGID_00000096037155027899726430000003377672684665991553_" style="overflow:visible;"/>
865 - </clipPath>
866 - <g style="clip-path:url(#SVGID_00000004509549875243981780000017806978581699248034_);">
867 - <polygon class="st3" points="2071.3,219.9 2087.2,227.8 2071.3,235.7 "/>
868 - <path class="st3" d="M2070.5,220.4v-1.9l2.6,1.3l-0.7,1.4l-1.4-0.7l0.4-0.7h0.8v0.6L2070.5,220.4L2070.5,220.4z M2070.5,222v-1.6
869 - h1.6v1.6H2070.5z M2070.5,223.6V222h1.6v1.6H2070.5z M2070.5,225.2v-1.6h1.6v1.6H2070.5z M2070.5,226.8v-1.6h1.6v1.6H2070.5z
870 - M2070.5,228.3v-1.6h1.6v1.6H2070.5z M2070.5,229.9v-1.6h1.6v1.6H2070.5z M2070.5,231.5v-1.6h1.6v1.6H2070.5z M2070.5,233.1v-1.6
871 - h1.6v1.6H2070.5z M2070.5,234.7v-1.6h1.6v1.6H2070.5z M2072.2,236.1l-1.7,0.8v-2.3h1.6v1h-0.8l-0.4-0.7l0.5-0.3L2072.2,236.1z
872 - M2073.6,235.4l-1.4,0.7l-0.7-1.4l1.4-0.7L2073.6,235.4z M2075,234.7l-1.4,0.7l-0.7-1.4l1.4-0.7L2075,234.7z M2076.5,234l-1.4,0.7
873 - l-0.7-1.4l1.4-0.7L2076.5,234z M2077.9,233.3l-1.4,0.7l-0.7-1.4l1.4-0.7L2077.9,233.3z M2079.3,232.6l-1.4,0.7l-0.7-1.4l1.4-0.7
874 - L2079.3,232.6z M2080.7,231.9l-1.4,0.7l-0.7-1.4l1.4-0.7L2080.7,231.9z M2082.1,231.1l-1.4,0.7l-0.7-1.4l1.4-0.7L2082.1,231.1z
875 - M2083.6,230.4l-1.4,0.7l-0.7-1.4l1.4-0.7L2083.6,230.4z M2085,229.7l-1.4,0.7l-0.7-1.4l1.4-0.7L2085,229.7z M2086.4,229l-1.4,0.7
876 - l-0.7-1.4l1.4-0.7L2086.4,229z M2087.3,226.9l1.7,0.8l-2.6,1.3l-0.7-1.4l1.2-0.6l0.4,0.7l-0.4,0.7l-0.3-0.1L2087.3,226.9
877 - L2087.3,226.9z M2085.9,226.2l1.4,0.7l-0.7,1.4l-1.4-0.7L2085.9,226.2z M2084.5,225.5l1.4,0.7l-0.7,1.4l-1.4-0.7L2084.5,225.5z
878 - M2083,224.8l1.4,0.7l-0.7,1.4l-1.4-0.7L2083,224.8z M2081.6,224l1.4,0.7l-0.7,1.4l-1.4-0.7L2081.6,224z M2080.2,223.3l1.4,0.7
879 - l-0.7,1.4l-1.4-0.7L2080.2,223.3z M2078.8,222.6l1.4,0.7l-0.7,1.4l-1.4-0.7L2078.8,222.6z M2077.4,221.9l1.4,0.7l-0.7,1.4
880 - l-1.4-0.7L2077.4,221.9z M2075.9,221.2l1.4,0.7l-0.7,1.4l-1.4-0.7L2075.9,221.2z M2074.5,220.5l1.4,0.7l-0.7,1.4l-1.4-0.7
881 - L2074.5,220.5z M2073.1,219.8l1.4,0.7l-0.7,1.4l-1.4-0.7L2073.1,219.8z"/>
882 - </g>
883 -</g>
884 -<g>
885 - <defs>
886 - <rect id="SVGID_00000057145579575648425470000000066675098518228397_" x="10" y="-315.3" width="2473" height="1264"/>
887 - </defs>
888 - <clipPath id="SVGID_00000139275487196970754910000015847525056595399091_">
889 - <use xlink:href="#SVGID_00000057145579575648425470000000066675098518228397_" style="overflow:visible;"/>
890 - </clipPath>
891 - <g style="clip-path:url(#SVGID_00000139275487196970754910000015847525056595399091_);">
892 - <path class="st27" d="M234.6,324.1l8.2-8.3c8.2-8.3,24.8-24.9,40.4-42.1c15.7-17.3,30.5-35.3,44.5-52.3c14-17,27.2-32.9,33.8-40.9
893 - l6.6-8"/>
894 - </g>
895 -</g>
896 -<g>
897 - <defs>
898 - <rect id="SVGID_00000088821363939539616590000009520657360209187983_" x="10" y="-315.3" width="2473" height="1264"/>
899 - </defs>
900 - <clipPath id="SVGID_00000029724248896774258190000015923189364124112830_">
901 - <use xlink:href="#SVGID_00000088821363939539616590000009520657360209187983_" style="overflow:visible;"/>
902 - </clipPath>
903 - <g style="clip-path:url(#SVGID_00000029724248896774258190000015923189364124112830_);">
904 - <g>
905 - <defs>
906 - <rect id="SVGID_00000169558521205561609540000014685052073866371752_" x="10" y="-315.3" width="2473" height="1264"/>
907 - </defs>
908 - <clipPath id="SVGID_00000005263606219827907090000016570189072241964983_">
909 - <use xlink:href="#SVGID_00000169558521205561609540000014685052073866371752_" style="overflow:visible;"/>
910 - </clipPath>
911 - <g style="clip-path:url(#SVGID_00000005263606219827907090000016570189072241964983_);">
912 - <g>
913 - <defs>
914 -
915 - <rect id="SVGID_00000139983687857284644730000016823614009493927078_" x="360.2" y="164.6" transform="matrix(0.6363 -0.7714 0.7714 0.6363 0.8254 346.7164)" width="15.8" height="15.8"/>
916 - </defs>
917 - <clipPath id="SVGID_00000107545988855502021540000003146258000133319305_">
918 - <use xlink:href="#SVGID_00000139983687857284644730000016823614009493927078_" style="overflow:visible;"/>
919 - </clipPath>
920 - <g style="clip-path:url(#SVGID_00000107545988855502021540000003146258000133319305_);">
921 - <polygon class="st3" points="357,173.6 373.2,166.4 369.2,183.7 "/>
922 - <path class="st3" d="M357,174.6l-1.4-1.2l2.6-1.2l0.6,1.4l-1.5,0.6l-0.3-0.7l0.5-0.6l0.4,0.4L357,174.6L357,174.6z
923 - M358.2,175.6l-1.2-1l1-1.2l1.2,1L358.2,175.6z M359.4,176.6l-1.2-1l1-1.2l1.2,1L359.4,176.6z M360.6,177.6l-1.2-1l1-1.2
924 - l1.2,1L360.6,177.6z M361.8,178.6l-1.2-1l1-1.2l1.2,1L361.8,178.6z M363.1,179.6l-1.2-1l1-1.2l1.2,1L363.1,179.6z
925 - M364.3,180.6l-1.2-1l1-1.2l1.2,1L364.3,180.6z M365.5,181.6l-1.2-1l1-1.2l1.2,1L365.5,181.6z M366.7,182.6l-1.2-1l1-1.2
926 - l1.2,1L366.7,182.6z M367.9,183.6l-1.2-1l1-1.2l1.2,1L367.9,183.6z M370.1,183.3l-0.4,1.8l-1.8-1.5l1-1.2l0.8,0.6l-0.5,0.6
927 - l-0.8-0.2l0.1-0.6L370.1,183.3L370.1,183.3z M370.5,181.7l-0.4,1.5l-1.5-0.4l0.4-1.5L370.5,181.7z M370.8,180.2l-0.4,1.5
928 - l-1.5-0.4l0.4-1.5L370.8,180.2z M371.2,178.7l-0.4,1.5l-1.5-0.4l0.4-1.5L371.2,178.7z M371.6,177.1l-0.4,1.5l-1.5-0.4l0.4-1.5
929 - L371.6,177.1z M371.9,175.6l-0.4,1.5l-1.5-0.4l0.4-1.5L371.9,175.6z M372.3,174l-0.4,1.5l-1.5-0.4l0.4-1.5L372.3,174z
930 - M372.6,172.5l-0.4,1.5l-1.5-0.4l0.4-1.5L372.6,172.5z M373,171l-0.4,1.5l-1.5-0.4l0.4-1.5L373,171z M373.4,169.4L373,171
931 - l-1.5-0.4l0.4-1.5L373.4,169.4z M373.7,167.9l-0.4,1.5l-1.5-0.4l0.4-1.5L373.7,167.9z M372.7,165.8l1.7-0.8l-0.6,2.8l-1.5-0.4
932 - l0.3-1.3l0.8,0.2l0.3,0.7l-0.3,0.1L372.7,165.8L372.7,165.8z M371.2,166.5l1.5-0.6l0.6,1.4l-1.5,0.6L371.2,166.5z
933 - M369.8,167.1l1.5-0.6l0.6,1.4l-1.5,0.6L369.8,167.1z M368.3,167.8l1.5-0.6l0.6,1.4l-1.5,0.6L368.3,167.8z M366.9,168.4
934 - l1.5-0.6l0.6,1.4l-1.5,0.6L366.9,168.4z M365.4,169l1.5-0.6l0.6,1.4l-1.5,0.6L365.4,169z M364,169.7l1.5-0.6l0.6,1.4l-1.5,0.6
935 - L364,169.7z M362.5,170.3l1.5-0.6l0.6,1.4l-1.5,0.6L362.5,170.3z M361.1,171l1.5-0.6l0.6,1.4l-1.5,0.6L361.1,171z
936 - M359.6,171.6l1.5-0.6l0.6,1.4l-1.5,0.6L359.6,171.6z M358.2,172.2l1.5-0.6l0.6,1.4l-1.5,0.6L358.2,172.2z"/>
937 - </g>
938 - </g>
939 - </g>
940 - </g>
941 - </g>
942 -</g>
943 -<g>
944 - <defs>
945 - <rect id="SVGID_00000062870936050302073310000007632015587384220044_" x="10" y="-315.3" width="2473" height="1264"/>
946 - </defs>
947 - <clipPath id="SVGID_00000025445213215486799710000010785446443408148887_">
948 - <use xlink:href="#SVGID_00000062870936050302073310000007632015587384220044_" style="overflow:visible;"/>
949 - </clipPath>
950 - <g style="clip-path:url(#SVGID_00000025445213215486799710000010785446443408148887_);">
951 - <path class="st27" d="M234.6,379.1l8.2-3.9c8.2-3.9,24.8-11.8,55.2-15.7s74.8-3.9,119.2-3.9s88.8,0,115.1-2.7s34.6-8.1,41.7-12.8
952 - c7.2-4.7,13.2-8.7,16.2-10.7l3-2"/>
953 - </g>
954 -</g>
955 -<g>
956 - <defs>
957 - <rect id="SVGID_00000179624020040826215050000002940362068015962267_" x="10" y="-315.3" width="2473" height="1264"/>
958 - </defs>
959 - <clipPath id="SVGID_00000014621905477050371350000002374342878743212728_">
960 - <use xlink:href="#SVGID_00000179624020040826215050000002940362068015962267_" style="overflow:visible;"/>
961 - </clipPath>
962 - <g style="clip-path:url(#SVGID_00000014621905477050371350000002374342878743212728_);">
963 - <g>
964 - <defs>
965 - <rect id="SVGID_00000162352253597826149870000012629678123735477439_" x="10" y="-315.3" width="2473" height="1264"/>
966 - </defs>
967 - <clipPath id="SVGID_00000011005545613074983700000006044319708566668180_">
968 - <use xlink:href="#SVGID_00000162352253597826149870000012629678123735477439_" style="overflow:visible;"/>
969 - </clipPath>
970 - <g style="clip-path:url(#SVGID_00000011005545613074983700000006044319708566668180_);">
971 - <g>
972 - <defs>
973 -
974 - <rect id="SVGID_00000129187429057239791310000009192780404463342236_" x="585.5" y="319.5" transform="matrix(0.8356 -0.5493 0.5493 0.8356 -82.3203 379.7809)" width="15.8" height="15.8"/>
975 - </defs>
976 - <clipPath id="SVGID_00000052801507160435428630000012323712548071194047_">
977 - <use xlink:href="#SVGID_00000129187429057239791310000009192780404463342236_" style="overflow:visible;"/>
978 - </clipPath>
979 - <g style="clip-path:url(#SVGID_00000052801507160435428630000012323712548071194047_);">
980 - <polygon class="st3" points="582.4,325.1 600,323 591.1,338.3 "/>
981 - <path class="st3" d="M582.1,326l-1-1.5l2.8-0.3l0.2,1.6l-1.6,0.2l-0.1-0.8l0.7-0.4l0.3,0.5L582.1,326L582.1,326z M582.9,327.3
982 - l-0.9-1.3l1.3-0.9l0.9,1.3L582.9,327.3z M583.8,328.7l-0.9-1.3l1.3-0.9l0.9,1.3L583.8,328.7z M584.7,330l-0.9-1.3l1.3-0.9
983 - l0.9,1.3L584.7,330z M585.5,331.3l-0.9-1.3l1.3-0.9l0.9,1.3L585.5,331.3z M586.4,332.6l-0.9-1.3l1.3-0.9l0.9,1.3L586.4,332.6z
984 - M587.3,333.9l-0.9-1.3l1.3-0.9l0.9,1.3L587.3,333.9z M588.2,335.3l-0.9-1.3l1.3-0.9l0.9,1.3L588.2,335.3z M589,336.6
985 - l-0.9-1.3l1.3-0.9l0.9,1.3L589,336.6z M589.9,337.9l-0.9-1.3l1.3-0.9l0.9,1.3L589.9,337.9z M592.1,338.2l-0.9,1.6l-1.3-1.9
986 - l1.3-0.9l0.6,0.9l-0.7,0.4l-0.7-0.4l0.3-0.5L592.1,338.2L592.1,338.2z M592.9,336.8l-0.8,1.4l-1.4-0.8l0.8-1.4L592.9,336.8z
987 - M593.7,335.5l-0.8,1.4l-1.4-0.8l0.8-1.4L593.7,335.5z M594.5,334.1l-0.8,1.4l-1.4-0.8l0.8-1.4L594.5,334.1z M595.2,332.7
988 - l-0.8,1.4l-1.4-0.8l0.8-1.4L595.2,332.7z M596,331.4l-0.8,1.4l-1.4-0.8l0.8-1.4L596,331.4z M596.8,330l-0.8,1.4l-1.4-0.8
989 - l0.8-1.4L596.8,330z M597.6,328.6l-0.8,1.4l-1.4-0.8l0.8-1.4L597.6,328.6z M598.4,327.3l-0.8,1.4l-1.4-0.8l0.8-1.4
990 - L598.4,327.3z M599.2,325.9l-0.8,1.4l-1.4-0.8l0.8-1.4L599.2,325.9z M600,324.5l-0.8,1.4l-1.4-0.8l0.8-1.4L600,324.5z
991 - M599.6,322.2l1.9-0.2l-1.5,2.5l-1.4-0.8l0.7-1.1l0.7,0.4l0.1,0.8l-0.3,0L599.6,322.2L599.6,322.2z M598,322.4l1.6-0.2
992 - l0.2,1.6l-1.6,0.2L598,322.4z M596.4,322.6l1.6-0.2l0.2,1.6l-1.6,0.2L596.4,322.6z M594.9,322.8l1.6-0.2l0.2,1.6l-1.6,0.2
993 - L594.9,322.8z M593.3,323l1.6-0.2l0.2,1.6l-1.6,0.2L593.3,323z M591.7,323.2l1.6-0.2l0.2,1.6l-1.6,0.2L591.7,323.2z
994 - M590.2,323.4l1.6-0.2l0.2,1.6l-1.6,0.2L590.2,323.4z M588.6,323.6l1.6-0.2l0.2,1.6l-1.6,0.2L588.6,323.6z M587,323.8l1.6-0.2
995 - l0.2,1.6l-1.6,0.2L587,323.8z M585.4,324l1.6-0.2l0.2,1.6l-1.6,0.2L585.4,324z M583.9,324.1l1.6-0.2l0.2,1.6l-1.6,0.2
996 - L583.9,324.1z"/>
997 - </g>
998 - </g>
999 - </g>
1000 - </g>
1001 - </g>
1002 -</g>
1003 -<g>
1004 - <defs>
1005 - <rect id="SVGID_00000072961319204898884260000000401353156917212851_" x="10" y="-315.3" width="2473" height="1264"/>
1006 - </defs>
1007 - <clipPath id="SVGID_00000094620367142509143220000013227772413196973952_">
1008 - <use xlink:href="#SVGID_00000072961319204898884260000000401353156917212851_" style="overflow:visible;"/>
1009 - </clipPath>
1010 - <g style="clip-path:url(#SVGID_00000094620367142509143220000013227772413196973952_);">
1011 - <path class="st27" d="M234.6,469.1l8.2,3.2c8.2,3.2,24.8,9.6,55.2,12.7c30.5,3.2,74.8,3.2,119.2,3.2h297.4c54.8,0,109.5,0,141-1
1012 - c31.5-1,39.8-3,46.7-4.7c7-1.7,12.7-3,15.5-3.7l2.8-0.7"/>
1013 - </g>
1014 -</g>
1015 -<g>
1016 - <defs>
1017 - <rect id="SVGID_00000133525657920242402900000004344918923691143100_" x="10" y="-315.3" width="2473" height="1264"/>
1018 - </defs>
1019 - <clipPath id="SVGID_00000072270648146907782340000010240768619606211714_">
1020 - <use xlink:href="#SVGID_00000133525657920242402900000004344918923691143100_" style="overflow:visible;"/>
1021 - </clipPath>
1022 - <g style="clip-path:url(#SVGID_00000072270648146907782340000010240768619606211714_);">
1023 - <g>
1024 - <defs>
1025 - <rect id="SVGID_00000068652079744201447600000000556594999236621698_" x="10" y="-315.3" width="2473" height="1264"/>
1026 - </defs>
1027 - <clipPath id="SVGID_00000088116653233820960690000006780014223573998981_">
1028 - <use xlink:href="#SVGID_00000068652079744201447600000000556594999236621698_" style="overflow:visible;"/>
1029 - </clipPath>
1030 - <g style="clip-path:url(#SVGID_00000088116653233820960690000006780014223573998981_);">
1031 - <g>
1032 - <defs>
1033 -
1034 - <rect id="SVGID_00000129927088779258199390000001162465988450498461_" x="912.9" y="470.2" transform="matrix(0.9721 -0.2345 0.2345 0.9721 -86.4308 229.2187)" width="15.8" height="15.8"/>
1035 - </defs>
1036 - <clipPath id="SVGID_00000178172888619500727950000005124755856499642295_">
1037 - <use xlink:href="#SVGID_00000129927088779258199390000001162465988450498461_" style="overflow:visible;"/>
1038 - </clipPath>
1039 - <g style="clip-path:url(#SVGID_00000178172888619500727950000005124755856499642295_);">
1040 - <polygon class="st3" points="911.2,472.3 928.5,476.3 914.9,487.7 "/>
1041 - <path class="st3" d="M910.6,473.1l-0.4-1.8l2.8,0.6l-0.4,1.5l-1.5-0.4l0.2-0.8l0.8-0.2l0.1,0.6L910.6,473.1L910.6,473.1z
1042 - M911,474.6l-0.4-1.5l1.5-0.4l0.4,1.5L911,474.6z M911.3,476.2l-0.4-1.5l1.5-0.4l0.4,1.5L911.3,476.2z M911.7,477.7l-0.4-1.5
1043 - l1.5-0.4l0.4,1.5L911.7,477.7z M912.1,479.2l-0.4-1.5l1.5-0.4l0.4,1.5L912.1,479.2z M912.4,480.8l-0.4-1.5l1.5-0.4l0.4,1.5
1044 - L912.4,480.8z M912.8,482.3l-0.4-1.5l1.5-0.4l0.4,1.5L912.8,482.3z M913.2,483.9l-0.4-1.5l1.5-0.4l0.4,1.5L913.2,483.9z
1045 - M913.5,485.4l-0.4-1.5l1.5-0.4l0.4,1.5L913.5,485.4z M913.9,486.9l-0.4-1.5l1.5-0.4l0.4,1.5L913.9,486.9z M915.9,488
1046 - l-1.4,1.2l-0.5-2.2l1.5-0.4l0.2,1l-0.8,0.2l-0.5-0.6l0.4-0.4L915.9,488L915.9,488z M917.1,487l-1.2,1l-1-1.2l1.2-1L917.1,487z
1047 - M918.3,485.9l-1.2,1l-1-1.2l1.2-1L918.3,485.9z M919.5,484.9l-1.2,1l-1-1.2l1.2-1L919.5,484.9z M920.7,483.9l-1.2,1l-1-1.2
1048 - l1.2-1L920.7,483.9z M921.9,482.9l-1.2,1l-1-1.2l1.2-1L921.9,482.9z M923.1,481.9l-1.2,1l-1-1.2l1.2-1L923.1,481.9z
1049 - M924.3,480.8l-1.2,1l-1-1.2l1.2-1L924.3,480.8z M925.5,479.8l-1.2,1l-1-1.2l1.2-1L925.5,479.8z M926.8,478.8l-1.2,1l-1-1.2
1050 - l1.2-1L926.8,478.8z M928,477.8l-1.2,1l-1-1.2l1.2-1L928,477.8z M928.3,475.5l1.8,0.4l-2.2,1.9l-1-1.2l1-0.8l0.5,0.6l-0.2,0.8
1051 - l-0.3-0.1L928.3,475.5L928.3,475.5z M926.8,475.1l1.5,0.4L928,477l-1.5-0.4L926.8,475.1z M925.3,474.8l1.5,0.4l-0.4,1.5
1052 - l-1.5-0.4L925.3,474.8z M923.7,474.4l1.5,0.4l-0.4,1.5l-1.5-0.4L923.7,474.4z M922.2,474.1l1.5,0.4l-0.4,1.5l-1.5-0.4
1053 - L922.2,474.1z M920.6,473.7l1.5,0.4l-0.4,1.5l-1.5-0.4L920.6,473.7z M919.1,473.3l1.5,0.4l-0.4,1.5l-1.5-0.4L919.1,473.3z
1054 - M917.6,473l1.5,0.4l-0.4,1.5l-1.5-0.4L917.6,473z M916,472.6l1.5,0.4l-0.4,1.5l-1.5-0.4L916,472.6z M914.5,472.3l1.5,0.4
1055 - l-0.4,1.5l-1.5-0.4L914.5,472.3z M912.9,471.9l1.5,0.4l-0.4,1.5l-1.5-0.4L912.9,471.9z"/>
1056 - </g>
1057 - </g>
1058 - </g>
1059 - </g>
1060 - </g>
1061 -</g>
1062 -<g>
1063 - <defs>
1064 - <rect id="SVGID_00000178903695516661426280000015533126112284351886_" x="10" y="-315.3" width="2473" height="1264"/>
1065 - </defs>
1066 - <clipPath id="SVGID_00000062156261096439352990000015326338217782033055_">
1067 - <use xlink:href="#SVGID_00000178903695516661426280000015533126112284351886_" style="overflow:visible;"/>
1068 - </clipPath>
1069 - <g style="clip-path:url(#SVGID_00000062156261096439352990000015326338217782033055_);">
1070 - <path class="st64" d="M186.5,93.1c0,1.8-0.1,3.7-0.3,5.5s-0.4,3.7-0.8,5.5s-0.8,3.6-1.3,5.3s-1.1,3.5-1.9,5.2
1071 - c-0.7,1.7-1.5,3.4-2.4,5s-1.8,3.2-2.8,4.7c-1,1.5-2.1,3-3.3,4.4c-1.2,1.4-2.4,2.8-3.7,4.1c-1.3,1.3-2.7,2.5-4.1,3.7
1072 - s-2.9,2.3-4.4,3.3c-1.5,1-3.1,2-4.7,2.8s-3.3,1.6-5,2.4c-1.7,0.7-3.4,1.3-5.2,1.9c-1.8,0.5-3.6,1-5.4,1.3s-3.6,0.6-5.5,0.8
1073 - s-3.7,0.3-5.5,0.3s-3.7-0.1-5.5-0.3c-1.8-0.2-3.7-0.4-5.5-0.8s-3.6-0.8-5.3-1.3s-3.5-1.1-5.2-1.9c-1.7-0.7-3.4-1.5-5-2.4
1074 - c-1.6-0.9-3.2-1.8-4.7-2.8c-1.5-1-3-2.1-4.4-3.3s-2.8-2.4-4.1-3.7c-1.3-1.3-2.5-2.7-3.7-4.1s-2.3-2.9-3.3-4.4
1075 - c-1-1.5-2-3.1-2.8-4.7c-0.9-1.6-1.7-3.3-2.4-5c-0.7-1.7-1.3-3.4-1.9-5.2c-0.5-1.8-1-3.6-1.3-5.3c-0.4-1.8-0.6-3.6-0.8-5.5
1076 - S74,95,74,93.1s0.1-3.7,0.3-5.5s0.4-3.7,0.8-5.5s0.8-3.6,1.3-5.3s1.2-3.5,1.9-5.2c0.7-1.7,1.5-3.4,2.4-5c0.9-1.6,1.8-3.2,2.8-4.7
1077 - c1-1.5,2.1-3,3.3-4.4c1.2-1.4,2.4-2.8,3.7-4.1c1.3-1.3,2.7-2.5,4.1-3.7s2.9-2.3,4.4-3.3c1.5-1,3.1-2,4.7-2.8s3.3-1.7,5-2.4
1078 - c1.7-0.7,3.4-1.3,5.2-1.9c1.8-0.5,3.6-1,5.3-1.3s3.6-0.6,5.5-0.8s3.7-0.3,5.5-0.3s3.7,0.1,5.5,0.3s3.6,0.5,5.5,0.8
1079 - s3.6,0.8,5.4,1.3c1.8,0.5,3.5,1.2,5.2,1.9c1.7,0.7,3.4,1.5,5,2.4c1.6,0.9,3.2,1.8,4.7,2.8c1.5,1,3,2.1,4.4,3.3
1080 - c1.4,1.2,2.8,2.4,4.1,3.7c1.3,1.3,2.5,2.7,3.7,4.1c1.2,1.4,2.3,2.9,3.3,4.4c1,1.5,2,3.1,2.8,4.7s1.6,3.3,2.4,5
1081 - c0.7,1.7,1.3,3.4,1.9,5.2s1,3.6,1.3,5.3c0.4,1.8,0.6,3.6,0.8,5.5S186.5,91.3,186.5,93.1z"/>
1082 - <path class="st65" d="M186.5,93.1c0,1.8-0.1,3.7-0.3,5.5s-0.4,3.7-0.8,5.5s-0.8,3.6-1.3,5.3s-1.1,3.5-1.9,5.2
1083 - c-0.7,1.7-1.5,3.4-2.4,5s-1.8,3.2-2.8,4.7c-1,1.5-2.1,3-3.3,4.4c-1.2,1.4-2.4,2.8-3.7,4.1c-1.3,1.3-2.7,2.5-4.1,3.7
1084 - s-2.9,2.3-4.4,3.3c-1.5,1-3.1,2-4.7,2.8s-3.3,1.6-5,2.4c-1.7,0.7-3.4,1.3-5.2,1.9c-1.8,0.5-3.6,1-5.4,1.3s-3.6,0.6-5.5,0.8
1085 - s-3.7,0.3-5.5,0.3s-3.7-0.1-5.5-0.3c-1.8-0.2-3.7-0.4-5.5-0.8s-3.6-0.8-5.3-1.3s-3.5-1.1-5.2-1.9c-1.7-0.7-3.4-1.5-5-2.4
1086 - c-1.6-0.9-3.2-1.8-4.7-2.8c-1.5-1-3-2.1-4.4-3.3s-2.8-2.4-4.1-3.7c-1.3-1.3-2.5-2.7-3.7-4.1s-2.3-2.9-3.3-4.4
1087 - c-1-1.5-2-3.1-2.8-4.7c-0.9-1.6-1.7-3.3-2.4-5c-0.7-1.7-1.3-3.4-1.9-5.2c-0.5-1.8-1-3.6-1.3-5.3c-0.4-1.8-0.6-3.6-0.8-5.5
1088 - S74,95,74,93.1s0.1-3.7,0.3-5.5s0.4-3.7,0.8-5.5s0.8-3.6,1.3-5.3s1.2-3.5,1.9-5.2c0.7-1.7,1.5-3.4,2.4-5c0.9-1.6,1.8-3.2,2.8-4.7
1089 - c1-1.5,2.1-3,3.3-4.4c1.2-1.4,2.4-2.8,3.7-4.1c1.3-1.3,2.7-2.5,4.1-3.7s2.9-2.3,4.4-3.3c1.5-1,3.1-2,4.7-2.8s3.3-1.7,5-2.4
1090 - c1.7-0.7,3.4-1.3,5.2-1.9c1.8-0.5,3.6-1,5.3-1.3s3.6-0.6,5.5-0.8s3.7-0.3,5.5-0.3s3.7,0.1,5.5,0.3s3.6,0.5,5.5,0.8
1091 - s3.6,0.8,5.4,1.3c1.8,0.5,3.5,1.2,5.2,1.9c1.7,0.7,3.4,1.5,5,2.4c1.6,0.9,3.2,1.8,4.7,2.8c1.5,1,3,2.1,4.4,3.3
1092 - c1.4,1.2,2.8,2.4,4.1,3.7c1.3,1.3,2.5,2.7,3.7,4.1c1.2,1.4,2.3,2.9,3.3,4.4c1,1.5,2,3.1,2.8,4.7s1.6,3.3,2.4,5
1093 - c0.7,1.7,1.3,3.4,1.9,5.2s1,3.6,1.3,5.3c0.4,1.8,0.6,3.6,0.8,5.5S186.5,91.3,186.5,93.1z"/>
1094 - <path class="st64" d="M176.6,93.1c0,1.5-0.1,3-0.2,4.5s-0.4,3-0.7,4.5s-0.7,3-1.1,4.4c-0.4,1.4-0.9,2.9-1.5,4.3s-1.2,2.8-1.9,4.1
1095 - c-0.7,1.3-1.5,2.6-2.3,3.9c-0.8,1.3-1.8,2.5-2.7,3.7s-2,2.3-3.1,3.4s-2.2,2.1-3.4,3c-1.2,1-2.4,1.9-3.6,2.7
1096 - c-1.3,0.8-2.6,1.6-3.9,2.3s-2.7,1.4-4.1,1.9s-2.8,1.1-4.3,1.5s-2.9,0.8-4.4,1.1c-1.5,0.3-3,0.5-4.5,0.7s-3,0.2-4.5,0.2
1097 - s-3-0.1-4.5-0.2s-3-0.4-4.5-0.7s-3-0.7-4.4-1.1s-2.9-0.9-4.3-1.5s-2.8-1.2-4.1-1.9c-1.3-0.7-2.6-1.5-3.9-2.3
1098 - c-1.3-0.8-2.5-1.8-3.7-2.7c-1.2-1-2.3-2-3.4-3.1s-2.1-2.2-3.1-3.4c-1-1.2-1.9-2.4-2.7-3.7s-1.6-2.6-2.3-3.9
1099 - c-0.7-1.3-1.4-2.7-1.9-4.1s-1.1-2.8-1.5-4.3s-0.8-2.9-1.1-4.4c-0.3-1.5-0.5-3-0.7-4.5s-0.2-3-0.2-4.5s0.1-3,0.2-4.5s0.4-3,0.7-4.5
1100 - c0.3-1.5,0.7-3,1.1-4.4s0.9-2.9,1.5-4.3s1.2-2.8,1.9-4.1c0.7-1.3,1.5-2.6,2.3-3.9s1.8-2.5,2.7-3.7s2-2.3,3.1-3.4s2.2-2.1,3.4-3
1101 - c1.2-1,2.4-1.9,3.7-2.7s2.6-1.6,3.9-2.3c1.3-0.7,2.7-1.4,4.1-1.9s2.8-1.1,4.3-1.5s2.9-0.8,4.4-1.1c1.5-0.3,3-0.5,4.5-0.7
1102 - c1.5-0.2,3-0.2,4.5-0.2s3,0.1,4.5,0.2s3,0.4,4.5,0.7s3,0.7,4.4,1.1s2.9,1,4.3,1.5s2.8,1.2,4.1,1.9c1.3,0.7,2.6,1.5,3.9,2.3
1103 - c1.3,0.8,2.5,1.8,3.6,2.7s2.3,2,3.4,3c1.1,1.1,2.1,2.2,3.1,3.4s1.9,2.4,2.7,3.7s1.6,2.6,2.3,3.9c0.7,1.3,1.4,2.7,1.9,4.1
1104 - s1.1,2.8,1.5,4.3s0.8,2.9,1.1,4.4c0.3,1.5,0.5,3,0.7,4.5S176.6,91.6,176.6,93.1z"/>
1105 - <path class="st65" d="M176.6,93.1c0,1.5-0.1,3-0.2,4.5s-0.4,3-0.7,4.5s-0.7,3-1.1,4.4c-0.4,1.4-0.9,2.9-1.5,4.3s-1.2,2.8-1.9,4.1
1106 - c-0.7,1.3-1.5,2.6-2.3,3.9c-0.8,1.3-1.8,2.5-2.7,3.7s-2,2.3-3.1,3.4s-2.2,2.1-3.4,3c-1.2,1-2.4,1.9-3.6,2.7
1107 - c-1.3,0.8-2.6,1.6-3.9,2.3s-2.7,1.4-4.1,1.9s-2.8,1.1-4.3,1.5s-2.9,0.8-4.4,1.1c-1.5,0.3-3,0.5-4.5,0.7s-3,0.2-4.5,0.2
1108 - s-3-0.1-4.5-0.2s-3-0.4-4.5-0.7s-3-0.7-4.4-1.1s-2.9-0.9-4.3-1.5s-2.8-1.2-4.1-1.9c-1.3-0.7-2.6-1.5-3.9-2.3
1109 - c-1.3-0.8-2.5-1.8-3.7-2.7c-1.2-1-2.3-2-3.4-3.1s-2.1-2.2-3.1-3.4c-1-1.2-1.9-2.4-2.7-3.7s-1.6-2.6-2.3-3.9
1110 - c-0.7-1.3-1.4-2.7-1.9-4.1s-1.1-2.8-1.5-4.3s-0.8-2.9-1.1-4.4c-0.3-1.5-0.5-3-0.7-4.5s-0.2-3-0.2-4.5s0.1-3,0.2-4.5s0.4-3,0.7-4.5
1111 - c0.3-1.5,0.7-3,1.1-4.4s0.9-2.9,1.5-4.3s1.2-2.8,1.9-4.1c0.7-1.3,1.5-2.6,2.3-3.9s1.8-2.5,2.7-3.7s2-2.3,3.1-3.4s2.2-2.1,3.4-3
1112 - c1.2-1,2.4-1.9,3.7-2.7s2.6-1.6,3.9-2.3c1.3-0.7,2.7-1.4,4.1-1.9s2.8-1.1,4.3-1.5s2.9-0.8,4.4-1.1c1.5-0.3,3-0.5,4.5-0.7
1113 - c1.5-0.2,3-0.2,4.5-0.2s3,0.1,4.5,0.2s3,0.4,4.5,0.7s3,0.7,4.4,1.1s2.9,1,4.3,1.5s2.8,1.2,4.1,1.9c1.3,0.7,2.6,1.5,3.9,2.3
1114 - c1.3,0.8,2.5,1.8,3.6,2.7s2.3,2,3.4,3c1.1,1.1,2.1,2.2,3.1,3.4s1.9,2.4,2.7,3.7s1.6,2.6,2.3,3.9c0.7,1.3,1.4,2.7,1.9,4.1
1115 - s1.1,2.8,1.5,4.3s0.8,2.9,1.1,4.4c0.3,1.5,0.5,3,0.7,4.5S176.6,91.6,176.6,93.1z"/>
1116 - </g>
1117 -</g>
1118 -<g>
1119 - <defs>
1120 - <rect id="SVGID_00000132781893549022272550000018371600524958144942_" x="98.8" y="69.3" width="63.4" height="47.5"/>
1121 - </defs>
1122 - <clipPath id="SVGID_00000080887401929999841660000005122288330060375721_">
1123 - <use xlink:href="#SVGID_00000132781893549022272550000018371600524958144942_" style="overflow:visible;"/>
1124 - </clipPath>
1125 - <g style="clip-path:url(#SVGID_00000080887401929999841660000005122288330060375721_);">
1126 - <text transform="matrix(1 0 0 1 98.75 104.21)" class="st67 st68 st69">User</text>
1127 - </g>
1128 -</g>
1129 -<g>
1130 - <defs>
1131 - <rect id="SVGID_00000029036823736704780860000011132067504775001534_" x="10" y="-315.3" width="2473" height="1264"/>
1132 - </defs>
1133 - <clipPath id="SVGID_00000156566297058199129770000005179827735076411057_">
1134 - <use xlink:href="#SVGID_00000029036823736704780860000011132067504775001534_" style="overflow:visible;"/>
1135 - </clipPath>
1136 - <g style="clip-path:url(#SVGID_00000156566297058199129770000005179827735076411057_);">
1137 - <path class="st64" d="M343.5,59.5h147.5c0.6,0,1.3,0.1,1.9,0.2c0.6,0.1,1.3,0.3,1.9,0.6c0.6,0.2,1.2,0.5,1.7,0.9
1138 - c0.5,0.4,1,0.8,1.5,1.2s0.9,1,1.2,1.5c0.4,0.5,0.7,1.1,0.9,1.7s0.4,1.2,0.6,1.9s0.2,1.3,0.2,1.9v87.1c0,0.6-0.1,1.3-0.2,1.9
1139 - s-0.3,1.3-0.6,1.9s-0.5,1.2-0.9,1.7c-0.4,0.5-0.8,1-1.2,1.5c-0.5,0.5-1,0.9-1.5,1.2s-1.1,0.7-1.7,0.9s-1.2,0.4-1.9,0.6
1140 - c-0.6,0.1-1.3,0.2-1.9,0.2H343.5c-0.6,0-1.3-0.1-1.9-0.2c-0.6-0.1-1.3-0.3-1.9-0.6c-0.6-0.2-1.2-0.6-1.7-0.9
1141 - c-0.5-0.4-1-0.8-1.5-1.2s-0.9-1-1.2-1.5c-0.4-0.5-0.7-1.1-0.9-1.7s-0.4-1.2-0.6-1.9c-0.1-0.6-0.2-1.3-0.2-1.9V69.3
1142 - c0-0.7,0.1-1.3,0.2-1.9s0.3-1.3,0.6-1.9s0.5-1.2,0.9-1.7c0.4-0.5,0.8-1,1.2-1.5s1-0.9,1.5-1.2s1.1-0.7,1.7-0.9s1.2-0.4,1.9-0.6
1143 - C342.3,59.5,342.9,59.4,343.5,59.5z"/>
1144 - <path class="st65" d="M343.5,59.5h147.5c0.6,0,1.3,0.1,1.9,0.2c0.6,0.1,1.3,0.3,1.9,0.6c0.6,0.2,1.2,0.5,1.7,0.9
1145 - c0.5,0.4,1,0.8,1.5,1.2s0.9,1,1.2,1.5c0.4,0.5,0.7,1.1,0.9,1.7s0.4,1.2,0.6,1.9s0.2,1.3,0.2,1.9v87.1c0,0.6-0.1,1.3-0.2,1.9
1146 - s-0.3,1.3-0.6,1.9s-0.5,1.2-0.9,1.7c-0.4,0.5-0.8,1-1.2,1.5c-0.5,0.5-1,0.9-1.5,1.2s-1.1,0.7-1.7,0.9s-1.2,0.4-1.9,0.6
1147 - c-0.6,0.1-1.3,0.2-1.9,0.2H343.5c-0.6,0-1.3-0.1-1.9-0.2c-0.6-0.1-1.3-0.3-1.9-0.6c-0.6-0.2-1.2-0.6-1.7-0.9
1148 - c-0.5-0.4-1-0.8-1.5-1.2s-0.9-1-1.2-1.5c-0.4-0.5-0.7-1.1-0.9-1.7s-0.4-1.2-0.6-1.9c-0.1-0.6-0.2-1.3-0.2-1.9V69.3
1149 - c0-0.7,0.1-1.3,0.2-1.9s0.3-1.3,0.6-1.9s0.5-1.2,0.9-1.7c0.4-0.5,0.8-1,1.2-1.5s1-0.9,1.5-1.2s1.1-0.7,1.7-0.9s1.2-0.4,1.9-0.6
1150 - C342.3,59.5,342.9,59.4,343.5,59.5z"/>
1151 - </g>
1152 -</g>
1153 -<g>
1154 - <defs>
1155 - <rect id="SVGID_00000068660001462182668330000016856357800891916193_" x="363.4" y="89.2" width="107.7" height="47.5"/>
1156 - </defs>
1157 - <clipPath id="SVGID_00000010296826536423246420000008756538965811108754_">
1158 - <use xlink:href="#SVGID_00000068660001462182668330000016856357800891916193_" style="overflow:visible;"/>
1159 - </clipPath>
1160 - <g style="clip-path:url(#SVGID_00000010296826536423246420000008756538965811108754_);">
1161 - <text transform="matrix(1 0 0 1 363.35 124.01)" class="st67 st68 st69">Agent 0</text>
1162 - </g>
1163 -</g>
1164 -<g>
1165 - <defs>
1166 - <rect id="SVGID_00000160880956627470160540000017395372307319774628_" x="10" y="-315.3" width="2473" height="1264"/>
1167 - </defs>
1168 - <clipPath id="SVGID_00000022545493823256924280000017212537841966101133_">
1169 - <use xlink:href="#SVGID_00000160880956627470160540000017395372307319774628_" style="overflow:visible;"/>
1170 - </clipPath>
1171 - <g style="clip-path:url(#SVGID_00000022545493823256924280000017212537841966101133_);">
1172 - <path class="st73" d="M25.8,283.9c0,0.4,0,0.7,0.1,1.1s0.2,0.7,0.4,1.1s0.4,0.7,0.6,1.1s0.5,0.7,0.9,1.1c0.3,0.4,0.7,0.7,1.1,1.1
1173 - c0.4,0.4,0.9,0.7,1.4,1.1s1,0.7,1.6,1.1c0.6,0.4,1.2,0.7,1.8,1s1.3,0.7,2.1,1s1.5,0.7,2.3,1c0.8,0.3,1.7,0.6,2.5,1
1174 - c0.9,0.3,1.8,0.6,2.7,0.9s1.9,0.6,3,0.9c1,0.3,2.1,0.6,3.2,0.9s2.2,0.6,3.3,0.8c1.2,0.3,2.3,0.5,3.5,0.8s2.4,0.5,3.7,0.8
1175 - s2.6,0.5,3.9,0.7c1.3,0.2,2.7,0.5,4,0.7s2.8,0.4,4.2,0.6s2.9,0.4,4.3,0.6s2.9,0.4,4.5,0.5c1.5,0.2,3,0.3,4.6,0.5
1176 - c1.5,0.2,3.1,0.3,4.7,0.5c1.6,0.1,3.2,0.3,4.8,0.4s3.2,0.2,4.9,0.4c1.6,0.1,3.3,0.2,4.9,0.3s3.3,0.2,5,0.2
1177 - c1.7,0.1,3.4,0.1,5.1,0.2s3.4,0.1,5.1,0.1c1.7,0,3.4,0.1,5.1,0.1s3.4,0,5.1,0s3.4,0,5.1,0c1.7,0,3.4,0,5.1-0.1
1178 - c1.7,0,3.4-0.1,5.1-0.1c1.7,0,3.4-0.1,5.1-0.2c1.7-0.1,3.3-0.1,5-0.2s3.3-0.2,4.9-0.3c1.6-0.1,3.3-0.2,4.9-0.4
1179 - c1.6-0.1,3.2-0.3,4.8-0.4s3.1-0.3,4.7-0.5s3.1-0.3,4.6-0.5s3-0.4,4.5-0.5s2.9-0.4,4.3-0.6c1.4-0.2,2.8-0.4,4.2-0.6s2.7-0.5,4-0.7
1180 - c1.3-0.2,2.6-0.5,3.9-0.7s2.5-0.5,3.7-0.8c1.2-0.3,2.4-0.5,3.5-0.8c1.1-0.3,2.3-0.6,3.4-0.8c1.1-0.3,2.1-0.6,3.1-0.9
1181 - c1-0.3,2-0.6,2.9-0.9s1.9-0.6,2.7-0.9s1.7-0.6,2.5-1s1.6-0.7,2.3-1c0.7-0.3,1.4-0.7,2.1-1c0.6-0.3,1.3-0.7,1.8-1s1.1-0.7,1.6-1.1
1182 - c0.5-0.4,0.9-0.7,1.4-1.1c0.4-0.4,0.8-0.7,1.1-1.1s0.6-0.7,0.9-1.1s0.5-0.7,0.6-1.1s0.3-0.7,0.4-1.1c0.1-0.4,0.1-0.7,0.1-1.1
1183 - s0-0.7-0.1-1.1c-0.1-0.4-0.2-0.7-0.4-1.1s-0.4-0.7-0.6-1.1c-0.2-0.4-0.5-0.7-0.9-1.1s-0.7-0.7-1.1-1.1c-0.4-0.4-0.9-0.7-1.4-1.1
1184 - s-1-0.7-1.6-1.1s-1.2-0.7-1.8-1c-0.6-0.3-1.4-0.7-2.1-1s-1.5-0.7-2.3-1c-0.8-0.3-1.6-0.6-2.5-1s-1.8-0.6-2.7-0.9
1185 - c-0.9-0.3-1.9-0.6-2.9-0.9c-1-0.3-2.1-0.6-3.1-0.9c-1.1-0.3-2.2-0.6-3.4-0.8c-1.1-0.3-2.3-0.5-3.5-0.8c-1.2-0.3-2.4-0.5-3.7-0.8
1186 - s-2.6-0.5-3.9-0.7c-1.3-0.2-2.7-0.5-4-0.7s-2.8-0.4-4.2-0.6c-1.4-0.2-2.9-0.4-4.3-0.6s-2.9-0.4-4.5-0.5c-1.5-0.2-3-0.3-4.6-0.5
1187 - c-1.5-0.2-3.1-0.3-4.7-0.5s-3.2-0.3-4.8-0.4s-3.2-0.2-4.9-0.4c-1.6-0.1-3.3-0.2-4.9-0.3s-3.3-0.2-5-0.2c-1.7-0.1-3.4-0.1-5.1-0.2
1188 - s-3.4-0.1-5.1-0.1s-3.4-0.1-5.1-0.1s-3.4,0-5.1,0s-3.4,0-5.1,0c-1.7,0-3.4,0-5.1,0.1c-1.7,0-3.4,0.1-5.1,0.1
1189 - c-1.7,0-3.4,0.1-5.1,0.2s-3.3,0.1-5,0.2s-3.3,0.2-4.9,0.3c-1.6,0.1-3.3,0.2-4.9,0.4c-1.6,0.1-3.2,0.3-4.8,0.4
1190 - c-1.6,0.1-3.1,0.3-4.7,0.5s-3.1,0.3-4.6,0.5s-3,0.4-4.5,0.5s-2.9,0.4-4.3,0.6s-2.8,0.4-4.2,0.6s-2.7,0.5-4,0.7
1191 - c-1.3,0.2-2.6,0.5-3.9,0.7s-2.5,0.5-3.7,0.8c-1.2,0.3-2.4,0.5-3.5,0.8c-1.2,0.3-2.3,0.6-3.3,0.8s-2.1,0.6-3.2,0.9
1192 - c-1,0.3-2,0.6-3,0.9s-1.9,0.6-2.7,0.9s-1.7,0.6-2.5,1c-0.8,0.3-1.6,0.7-2.3,1c-0.7,0.3-1.4,0.7-2.1,1c-0.7,0.3-1.3,0.7-1.8,1
1193 - c-0.6,0.4-1.1,0.7-1.6,1.1c-0.5,0.4-1,0.7-1.4,1.1c-0.4,0.4-0.8,0.7-1.1,1.1s-0.6,0.7-0.9,1.1s-0.5,0.7-0.6,1.1s-0.3,0.7-0.4,1.1
1194 - S25.8,283.5,25.8,283.9l0,290c0,0.4,0,0.7,0.1,1.1c0.1,0.4,0.2,0.7,0.4,1.1s0.4,0.7,0.6,1.1c0.2,0.4,0.5,0.7,0.9,1.1
1195 - c0.3,0.4,0.7,0.7,1.1,1.1s0.9,0.7,1.4,1.1s1,0.7,1.6,1.1c0.6,0.3,1.2,0.7,1.8,1c0.7,0.3,1.3,0.7,2.1,1c0.7,0.3,1.5,0.7,2.3,1
1196 - s1.7,0.7,2.5,1c0.9,0.3,1.8,0.6,2.7,0.9s1.9,0.6,3,0.9s2.1,0.6,3.2,0.9s2.2,0.6,3.3,0.8c1.2,0.3,2.3,0.5,3.5,0.8s2.4,0.5,3.7,0.8
1197 - s2.6,0.5,3.9,0.7s2.7,0.5,4,0.7s2.8,0.4,4.2,0.6c1.4,0.2,2.9,0.4,4.3,0.6s2.9,0.4,4.5,0.5c1.5,0.2,3,0.3,4.6,0.5
1198 - c1.5,0.2,3.1,0.3,4.7,0.5c1.6,0.1,3.2,0.3,4.8,0.4s3.2,0.2,4.9,0.3c1.6,0.1,3.3,0.2,4.9,0.3c1.7,0.1,3.3,0.2,5,0.2
1199 - s3.4,0.1,5.1,0.2s3.4,0.1,5.1,0.1c1.7,0,3.4,0.1,5.1,0.1s3.4,0,5.1,0s3.4,0,5.1,0c1.7,0,3.4,0,5.1-0.1c1.7,0,3.4-0.1,5.1-0.1
1200 - c1.7,0,3.4-0.1,5.1-0.2c1.7-0.1,3.3-0.2,5-0.2c1.7-0.1,3.3-0.2,4.9-0.3c1.6-0.1,3.3-0.2,4.9-0.3c1.6-0.1,3.2-0.3,4.8-0.4
1201 - s3.1-0.3,4.7-0.5s3.1-0.3,4.6-0.5s3-0.4,4.5-0.5s2.9-0.4,4.3-0.6c1.4-0.2,2.8-0.4,4.2-0.6s2.7-0.5,4-0.7c1.3-0.2,2.6-0.5,3.9-0.7
1202 - s2.5-0.5,3.7-0.8c1.2-0.3,2.4-0.5,3.5-0.8c1.1-0.3,2.3-0.6,3.4-0.8c1.1-0.3,2.1-0.6,3.1-0.9c1-0.3,2-0.6,2.9-0.9s1.9-0.6,2.7-0.9
1203 - s1.7-0.6,2.5-1c0.8-0.3,1.6-0.7,2.3-1c0.7-0.3,1.4-0.7,2.1-1c0.6-0.3,1.3-0.7,1.8-1c0.6-0.3,1.1-0.7,1.6-1.1
1204 - c0.5-0.3,0.9-0.7,1.4-1.1s0.8-0.7,1.1-1.1s0.6-0.7,0.9-1.1s0.5-0.7,0.6-1.1s0.3-0.7,0.4-1.1c0.1-0.4,0.1-0.7,0.1-1.1v-290"/>
1205 - <path class="st74" d="M25.8,283.9c0,0.4,0,0.7,0.1,1.1s0.2,0.7,0.4,1.1s0.4,0.7,0.6,1.1s0.5,0.7,0.9,1.1c0.3,0.4,0.7,0.7,1.1,1.1
1206 - c0.4,0.4,0.9,0.7,1.4,1.1s1,0.7,1.6,1.1c0.6,0.4,1.2,0.7,1.8,1s1.3,0.7,2.1,1s1.5,0.7,2.3,1c0.8,0.3,1.7,0.6,2.5,1
1207 - c0.9,0.3,1.8,0.6,2.7,0.9s1.9,0.6,3,0.9c1,0.3,2.1,0.6,3.2,0.9s2.2,0.6,3.3,0.8c1.2,0.3,2.3,0.5,3.5,0.8s2.4,0.5,3.7,0.8
1208 - s2.6,0.5,3.9,0.7c1.3,0.2,2.7,0.5,4,0.7s2.8,0.4,4.2,0.6s2.9,0.4,4.3,0.6s2.9,0.4,4.5,0.5c1.5,0.2,3,0.3,4.6,0.5
1209 - c1.5,0.2,3.1,0.3,4.7,0.5c1.6,0.1,3.2,0.3,4.8,0.4s3.2,0.2,4.9,0.4c1.6,0.1,3.3,0.2,4.9,0.3s3.3,0.2,5,0.2
1210 - c1.7,0.1,3.4,0.1,5.1,0.2s3.4,0.1,5.1,0.1c1.7,0,3.4,0.1,5.1,0.1s3.4,0,5.1,0s3.4,0,5.1,0c1.7,0,3.4,0,5.1-0.1
1211 - c1.7,0,3.4-0.1,5.1-0.1c1.7,0,3.4-0.1,5.1-0.2c1.7-0.1,3.3-0.1,5-0.2s3.3-0.2,4.9-0.3c1.6-0.1,3.3-0.2,4.9-0.4
1212 - c1.6-0.1,3.2-0.3,4.8-0.4s3.1-0.3,4.7-0.5s3.1-0.3,4.6-0.5s3-0.4,4.5-0.5s2.9-0.4,4.3-0.6c1.4-0.2,2.8-0.4,4.2-0.6s2.7-0.5,4-0.7
1213 - c1.3-0.2,2.6-0.5,3.9-0.7s2.5-0.5,3.7-0.8c1.2-0.3,2.4-0.5,3.5-0.8c1.1-0.3,2.3-0.6,3.4-0.8c1.1-0.3,2.1-0.6,3.1-0.9
1214 - c1-0.3,2-0.6,2.9-0.9s1.9-0.6,2.7-0.9s1.7-0.6,2.5-1s1.6-0.7,2.3-1c0.7-0.3,1.4-0.7,2.1-1c0.6-0.3,1.3-0.7,1.8-1s1.1-0.7,1.6-1.1
1215 - c0.5-0.4,0.9-0.7,1.4-1.1c0.4-0.4,0.8-0.7,1.1-1.1s0.6-0.7,0.9-1.1s0.5-0.7,0.6-1.1s0.3-0.7,0.4-1.1c0.1-0.4,0.1-0.7,0.1-1.1
1216 - s0-0.7-0.1-1.1c-0.1-0.4-0.2-0.7-0.4-1.1s-0.4-0.7-0.6-1.1c-0.2-0.4-0.5-0.7-0.9-1.1s-0.7-0.7-1.1-1.1c-0.4-0.4-0.9-0.7-1.4-1.1
1217 - s-1-0.7-1.6-1.1s-1.2-0.7-1.8-1c-0.6-0.3-1.4-0.7-2.1-1s-1.5-0.7-2.3-1c-0.8-0.3-1.6-0.6-2.5-1s-1.8-0.6-2.7-0.9
1218 - c-0.9-0.3-1.9-0.6-2.9-0.9c-1-0.3-2.1-0.6-3.1-0.9c-1.1-0.3-2.2-0.6-3.4-0.8c-1.1-0.3-2.3-0.5-3.5-0.8c-1.2-0.3-2.4-0.5-3.7-0.8
1219 - s-2.6-0.5-3.9-0.7c-1.3-0.2-2.7-0.5-4-0.7s-2.8-0.4-4.2-0.6c-1.4-0.2-2.9-0.4-4.3-0.6s-2.9-0.4-4.5-0.5c-1.5-0.2-3-0.3-4.6-0.5
1220 - c-1.5-0.2-3.1-0.3-4.7-0.5s-3.2-0.3-4.8-0.4s-3.2-0.2-4.9-0.4c-1.6-0.1-3.3-0.2-4.9-0.3s-3.3-0.2-5-0.2c-1.7-0.1-3.4-0.1-5.1-0.2
1221 - s-3.4-0.1-5.1-0.1s-3.4-0.1-5.1-0.1s-3.4,0-5.1,0s-3.4,0-5.1,0c-1.7,0-3.4,0-5.1,0.1c-1.7,0-3.4,0.1-5.1,0.1
1222 - c-1.7,0-3.4,0.1-5.1,0.2s-3.3,0.1-5,0.2s-3.3,0.2-4.9,0.3c-1.6,0.1-3.3,0.2-4.9,0.4c-1.6,0.1-3.2,0.3-4.8,0.4
1223 - c-1.6,0.1-3.1,0.3-4.7,0.5s-3.1,0.3-4.6,0.5s-3,0.4-4.5,0.5s-2.9,0.4-4.3,0.6s-2.8,0.4-4.2,0.6s-2.7,0.5-4,0.7
1224 - c-1.3,0.2-2.6,0.5-3.9,0.7s-2.5,0.5-3.7,0.8c-1.2,0.3-2.4,0.5-3.5,0.8c-1.2,0.3-2.3,0.6-3.3,0.8s-2.1,0.6-3.2,0.9
1225 - c-1,0.3-2,0.6-3,0.9s-1.9,0.6-2.7,0.9s-1.7,0.6-2.5,1c-0.8,0.3-1.6,0.7-2.3,1c-0.7,0.3-1.4,0.7-2.1,1c-0.7,0.3-1.3,0.7-1.8,1
1226 - c-0.6,0.4-1.1,0.7-1.6,1.1c-0.5,0.4-1,0.7-1.4,1.1c-0.4,0.4-0.8,0.7-1.1,1.1s-0.6,0.7-0.9,1.1s-0.5,0.7-0.6,1.1s-0.3,0.7-0.4,1.1
1227 - S25.8,283.5,25.8,283.9l0,290c0,0.4,0,0.7,0.1,1.1c0.1,0.4,0.2,0.7,0.4,1.1s0.4,0.7,0.6,1.1c0.2,0.4,0.5,0.7,0.9,1.1
1228 - c0.3,0.4,0.7,0.7,1.1,1.1s0.9,0.7,1.4,1.1s1,0.7,1.6,1.1c0.6,0.3,1.2,0.7,1.8,1c0.7,0.3,1.3,0.7,2.1,1c0.7,0.3,1.5,0.7,2.3,1
1229 - s1.7,0.7,2.5,1c0.9,0.3,1.8,0.6,2.7,0.9s1.9,0.6,3,0.9s2.1,0.6,3.2,0.9s2.2,0.6,3.3,0.8c1.2,0.3,2.3,0.5,3.5,0.8s2.4,0.5,3.7,0.8
1230 - s2.6,0.5,3.9,0.7s2.7,0.5,4,0.7s2.8,0.4,4.2,0.6c1.4,0.2,2.9,0.4,4.3,0.6s2.9,0.4,4.5,0.5c1.5,0.2,3,0.3,4.6,0.5
1231 - c1.5,0.2,3.1,0.3,4.7,0.5c1.6,0.1,3.2,0.3,4.8,0.4s3.2,0.2,4.9,0.3c1.6,0.1,3.3,0.2,4.9,0.3c1.7,0.1,3.3,0.2,5,0.2
1232 - s3.4,0.1,5.1,0.2s3.4,0.1,5.1,0.1c1.7,0,3.4,0.1,5.1,0.1s3.4,0,5.1,0s3.4,0,5.1,0c1.7,0,3.4,0,5.1-0.1c1.7,0,3.4-0.1,5.1-0.1
1233 - c1.7,0,3.4-0.1,5.1-0.2c1.7-0.1,3.3-0.2,5-0.2c1.7-0.1,3.3-0.2,4.9-0.3c1.6-0.1,3.3-0.2,4.9-0.3c1.6-0.1,3.2-0.3,4.8-0.4
1234 - s3.1-0.3,4.7-0.5s3.1-0.3,4.6-0.5s3-0.4,4.5-0.5s2.9-0.4,4.3-0.6c1.4-0.2,2.8-0.4,4.2-0.6s2.7-0.5,4-0.7c1.3-0.2,2.6-0.5,3.9-0.7
1235 - s2.5-0.5,3.7-0.8c1.2-0.3,2.4-0.5,3.5-0.8c1.1-0.3,2.3-0.6,3.4-0.8c1.1-0.3,2.1-0.6,3.1-0.9c1-0.3,2-0.6,2.9-0.9s1.9-0.6,2.7-0.9
1236 - s1.7-0.6,2.5-1c0.8-0.3,1.6-0.7,2.3-1c0.7-0.3,1.4-0.7,2.1-1c0.6-0.3,1.3-0.7,1.8-1c0.6-0.3,1.1-0.7,1.6-1.1
1237 - c0.5-0.3,0.9-0.7,1.4-1.1s0.8-0.7,1.1-1.1s0.6-0.7,0.9-1.1s0.5-0.7,0.6-1.1s0.3-0.7,0.4-1.1c0.1-0.4,0.1-0.7,0.1-1.1v-290"/>
1238 - </g>
1239 -</g>
1240 -<g>
1241 - <defs>
1242 - <rect id="SVGID_00000183227778509929802560000018397401592712839820_" x="40.7" y="329.8" width="179" height="237.6"/>
1243 - </defs>
1244 - <clipPath id="SVGID_00000145738413524748955610000004738186524440133039_">
1245 - <use xlink:href="#SVGID_00000183227778509929802560000018397401592712839820_" style="overflow:visible;"/>
1246 - </clipPath>
1247 - <g style="clip-path:url(#SVGID_00000145738413524748955610000004738186524440133039_);">
1248 - <text transform="matrix(1 0 0 1 70.82 364.69)" class="st67 st68 st69">Memory</text>
1249 - <text transform="matrix(1 0 0 1 177.96 364.69)" class="st67 st68 st69">,</text>
1250 - <text transform="matrix(1 0 0 1 48.1 412.22)" class="st67 st68 st69">K</text>
1251 - <text transform="matrix(1 0 0 1 65.35 412.22)" class="st67 st68 st69">nowledge,</text>
1252 - <text transform="matrix(1 0 0 1 40.7 459.74)" class="st67 st68 st69">Instruments,</text>
1253 - <text transform="matrix(1 0 0 1 66.99 507.27)" class="st67 st68 st69">P</text>
1254 - <text transform="matrix(1 0 0 1 83.17 507.27)" class="st67 st68 st69">rompts,</text>
1255 - <text transform="matrix(1 0 0 1 55.72 554.8)" class="st67 st68 st69">Extensions</text>
1256 - </g>
1257 -</g>
1258 -<g>
1259 - <defs>
1260 - <rect id="SVGID_00000155836776301372318160000013925065778048359586_" x="10" y="-315.3" width="2473" height="1264"/>
1261 - </defs>
1262 - <clipPath id="SVGID_00000096023652276183689800000006616743646947762825_">
1263 - <use xlink:href="#SVGID_00000155836776301372318160000013925065778048359586_" style="overflow:visible;"/>
1264 - </clipPath>
1265 - <g style="clip-path:url(#SVGID_00000096023652276183689800000006616743646947762825_);">
1266 - <path class="st64" d="M609.9,170.4h209.6c0.7,0,1.3,0.1,1.9,0.2s1.3,0.3,1.9,0.6s1.2,0.6,1.7,0.9c0.5,0.4,1,0.8,1.5,1.2
1267 - c0.5,0.5,0.9,1,1.2,1.5s0.7,1.1,0.9,1.7s0.4,1.2,0.6,1.9c0.1,0.6,0.2,1.3,0.2,1.9v134.7c0,0.6-0.1,1.3-0.2,1.9
1268 - c-0.1,0.6-0.3,1.3-0.6,1.9c-0.2,0.6-0.5,1.2-0.9,1.7c-0.4,0.5-0.8,1-1.2,1.5c-0.5,0.5-1,0.9-1.5,1.2c-0.5,0.4-1.1,0.7-1.7,0.9
1269 - c-0.6,0.2-1.2,0.4-1.9,0.6c-0.6,0.1-1.3,0.2-1.9,0.2H609.9c-0.7,0-1.3-0.1-1.9-0.2s-1.3-0.3-1.9-0.6s-1.2-0.5-1.7-0.9
1270 - c-0.5-0.4-1-0.8-1.5-1.2c-0.5-0.5-0.9-1-1.2-1.5s-0.7-1.1-0.9-1.7s-0.4-1.2-0.6-1.9c-0.1-0.6-0.2-1.3-0.2-1.9V180.2
1271 - c0-0.6,0.1-1.3,0.2-1.9s0.3-1.3,0.6-1.9s0.5-1.2,0.9-1.7c0.4-0.5,0.8-1,1.2-1.5c0.5-0.5,1-0.9,1.5-1.2s1.1-0.7,1.7-0.9
1272 - c0.6-0.2,1.2-0.4,1.9-0.6C608.6,170.4,609.2,170.3,609.9,170.4L609.9,170.4z"/>
1273 - <path class="st65" d="M609.9,170.4h209.6c0.7,0,1.3,0.1,1.9,0.2s1.3,0.3,1.9,0.6s1.2,0.6,1.7,0.9c0.5,0.4,1,0.8,1.5,1.2
1274 - c0.5,0.5,0.9,1,1.2,1.5s0.7,1.1,0.9,1.7s0.4,1.2,0.6,1.9c0.1,0.6,0.2,1.3,0.2,1.9v134.7c0,0.6-0.1,1.3-0.2,1.9
1275 - c-0.1,0.6-0.3,1.3-0.6,1.9c-0.2,0.6-0.5,1.2-0.9,1.7c-0.4,0.5-0.8,1-1.2,1.5c-0.5,0.5-1,0.9-1.5,1.2c-0.5,0.4-1.1,0.7-1.7,0.9
1276 - c-0.6,0.2-1.2,0.4-1.9,0.6c-0.6,0.1-1.3,0.2-1.9,0.2H609.9c-0.7,0-1.3-0.1-1.9-0.2s-1.3-0.3-1.9-0.6s-1.2-0.5-1.7-0.9
1277 - c-0.5-0.4-1-0.8-1.5-1.2c-0.5-0.5-0.9-1-1.2-1.5s-0.7-1.1-0.9-1.7s-0.4-1.2-0.6-1.9c-0.1-0.6-0.2-1.3-0.2-1.9V180.2
1278 - c0-0.6,0.1-1.3,0.2-1.9s0.3-1.3,0.6-1.9s0.5-1.2,0.9-1.7c0.4-0.5,0.8-1,1.2-1.5c0.5-0.5,1-0.9,1.5-1.2s1.1-0.7,1.7-0.9
1279 - c0.6-0.2,1.2-0.4,1.9-0.6C608.6,170.4,609.2,170.3,609.9,170.4L609.9,170.4z"/>
1280 - </g>
1281 -</g>
1282 -<g>
1283 - <defs>
1284 - <rect id="SVGID_00000061437844464511305790000004334658053585738909_" x="629.7" y="200.1" width="169.5" height="95.1"/>
1285 - </defs>
1286 - <clipPath id="SVGID_00000004523263253993653810000003690484622985944761_">
1287 - <use xlink:href="#SVGID_00000061437844464511305790000004334658053585738909_" style="overflow:visible;"/>
1288 - </clipPath>
1289 - <g style="clip-path:url(#SVGID_00000004523263253993653810000003690484622985944761_);">
1290 - <text transform="matrix(1 0 0 1 629.71 234.91)" class="st67 st68 st69">Subordinate</text>
1291 - <text transform="matrix(1 0 0 1 660.75 282.44)" class="st67 st68 st69">Agent 1</text>
1292 - </g>
1293 -</g>
1294 -<g>
1295 - <defs>
1296 - <rect id="SVGID_00000117638275231095390600000014238681609826865556_" x="10" y="-315.3" width="2473" height="1264"/>
1297 - </defs>
1298 - <clipPath id="SVGID_00000134937209363775423320000000529378778296655548_">
1299 - <use xlink:href="#SVGID_00000117638275231095390600000014238681609826865556_" style="overflow:visible;"/>
1300 - </clipPath>
1301 - <g style="clip-path:url(#SVGID_00000134937209363775423320000000529378778296655548_);">
1302 - <path class="st64" d="M938.4,371.4H1148c0.7,0,1.3,0.1,1.9,0.2s1.3,0.3,1.9,0.6s1.2,0.5,1.7,0.9c0.5,0.4,1,0.8,1.5,1.2
1303 - c0.5,0.5,0.9,1,1.2,1.5s0.7,1.1,0.9,1.7s0.4,1.2,0.6,1.9s0.2,1.3,0.2,1.9V516c0,0.7-0.1,1.3-0.2,1.9c-0.1,0.6-0.3,1.3-0.6,1.9
1304 - s-0.6,1.2-0.9,1.7s-0.8,1-1.2,1.5s-1,0.9-1.5,1.2s-1.1,0.7-1.7,0.9s-1.2,0.4-1.9,0.6c-0.6,0.1-1.3,0.2-1.9,0.2H938.4
1305 - c-0.7,0-1.3-0.1-1.9-0.2s-1.3-0.3-1.9-0.6s-1.2-0.5-1.7-0.9s-1-0.8-1.5-1.2c-0.5-0.5-0.9-1-1.2-1.5s-0.7-1.1-0.9-1.7
1306 - c-0.2-0.6-0.4-1.2-0.6-1.9c-0.1-0.6-0.2-1.3-0.2-1.9V381.3c0-0.6,0.1-1.3,0.2-1.9c0.1-0.6,0.3-1.3,0.6-1.9
1307 - c0.2-0.6,0.5-1.2,0.9-1.7c0.4-0.5,0.8-1,1.2-1.5c0.5-0.5,1-0.9,1.5-1.2c0.5-0.4,1.1-0.7,1.7-0.9c0.6-0.2,1.2-0.4,1.9-0.6
1308 - C937.1,371.5,937.7,371.4,938.4,371.4L938.4,371.4z"/>
1309 - <path class="st65" d="M938.4,371.4H1148c0.7,0,1.3,0.1,1.9,0.2s1.3,0.3,1.9,0.6s1.2,0.5,1.7,0.9c0.5,0.4,1,0.8,1.5,1.2
1310 - c0.5,0.5,0.9,1,1.2,1.5s0.7,1.1,0.9,1.7s0.4,1.2,0.6,1.9s0.2,1.3,0.2,1.9V516c0,0.7-0.1,1.3-0.2,1.9c-0.1,0.6-0.3,1.3-0.6,1.9
1311 - s-0.6,1.2-0.9,1.7s-0.8,1-1.2,1.5s-1,0.9-1.5,1.2s-1.1,0.7-1.7,0.9s-1.2,0.4-1.9,0.6c-0.6,0.1-1.3,0.2-1.9,0.2H938.4
1312 - c-0.7,0-1.3-0.1-1.9-0.2s-1.3-0.3-1.9-0.6s-1.2-0.5-1.7-0.9s-1-0.8-1.5-1.2c-0.5-0.5-0.9-1-1.2-1.5s-0.7-1.1-0.9-1.7
1313 - c-0.2-0.6-0.4-1.2-0.6-1.9c-0.1-0.6-0.2-1.3-0.2-1.9V381.3c0-0.6,0.1-1.3,0.2-1.9c0.1-0.6,0.3-1.3,0.6-1.9
1314 - c0.2-0.6,0.5-1.2,0.9-1.7c0.4-0.5,0.8-1,1.2-1.5c0.5-0.5,1-0.9,1.5-1.2c0.5-0.4,1.1-0.7,1.7-0.9c0.6-0.2,1.2-0.4,1.9-0.6
1315 - C937.1,371.5,937.7,371.4,938.4,371.4L938.4,371.4z"/>
1316 - </g>
1317 -</g>
1318 -<g>
1319 - <defs>
1320 - <rect id="SVGID_00000058581477882271925460000015288132986745826203_" x="958.2" y="401.1" width="169.5" height="95.1"/>
1321 - </defs>
1322 - <clipPath id="SVGID_00000039815150709407115820000010818935686328693686_">
1323 - <use xlink:href="#SVGID_00000058581477882271925460000015288132986745826203_" style="overflow:visible;"/>
1324 - </clipPath>
1325 - <g style="clip-path:url(#SVGID_00000039815150709407115820000010818935686328693686_);">
1326 - <text transform="matrix(1 0 0 1 958.18 435.98)" class="st67 st68 st69">Subordinate</text>
1327 - <text transform="matrix(1 0 0 1 989.22 483.51)" class="st67 st68 st69">Agent 2</text>
1328 - </g>
1329 -</g>
1330 -<g>
1331 - <defs>
1332 - <rect id="SVGID_00000181793847036937054310000016937832035254460852_" x="10" y="-315.3" width="2473" height="1264"/>
1333 - </defs>
1334 - <clipPath id="SVGID_00000000200106441355962520000008552993502165275056_">
1335 - <use xlink:href="#SVGID_00000181793847036937054310000016937832035254460852_" style="overflow:visible;"/>
1336 - </clipPath>
1337 - <g style="clip-path:url(#SVGID_00000000200106441355962520000008552993502165275056_);">
1338 -
1339 - <rect x="1283" y="165" transform="matrix(0.7071 -0.7071 0.7071 0.7071 233.0873 1018.3026)" class="st73" width="125.6" height="125.6"/>
1340 -
1341 - <rect x="1283" y="165" transform="matrix(0.7071 -0.7071 0.7071 0.7071 233.0873 1018.3026)" class="st74" width="125.6" height="125.6"/>
1342 - </g>
1343 -</g>
1344 -<g>
1345 - <defs>
1346 - <rect id="SVGID_00000093160866362353890040000000580848089041828798_" x="1310.4" y="204" width="71.3" height="47.5"/>
1347 - </defs>
1348 - <clipPath id="SVGID_00000046301876782948682840000018261966658233217665_">
1349 - <use xlink:href="#SVGID_00000093160866362353890040000000580848089041828798_" style="overflow:visible;"/>
1350 - </clipPath>
1351 - <g style="clip-path:url(#SVGID_00000046301876782948682840000018261966658233217665_);">
1352 - <text transform="matrix(1 0 0 1 1310.42 238.87)" class="st67 st68 st69">T</text>
1353 - <text transform="matrix(1 0 0 1 1324.87 238.87)" class="st67 st68 st69">ools</text>
1354 - </g>
1355 -</g>
1356 -<g>
1357 - <defs>
1358 - <rect id="SVGID_00000162340011057825243000000010881783801392862603_" x="10" y="-315.3" width="2473" height="1264"/>
1359 - </defs>
1360 - <clipPath id="SVGID_00000126323625052143002250000000534315234651050423_">
1361 - <use xlink:href="#SVGID_00000162340011057825243000000010881783801392862603_" style="overflow:visible;"/>
1362 - </clipPath>
1363 - <g style="clip-path:url(#SVGID_00000126323625052143002250000000534315234651050423_);">
1364 - <rect x="1583.1" y="174.3" class="st73" width="405.1" height="106.9"/>
1365 - <rect x="1583.1" y="174.3" class="st74" width="405.1" height="106.9"/>
1366 - </g>
1367 -</g>
1368 -<g>
1369 - <defs>
1370 - <rect id="SVGID_00000122697829781211708650000012154488265258970809_" x="1642.5" y="204" width="286.8" height="47.5"/>
1371 - </defs>
1372 - <clipPath id="SVGID_00000044163849903802845590000005483808105038946735_">
1373 - <use xlink:href="#SVGID_00000122697829781211708650000012154488265258970809_" style="overflow:visible;"/>
1374 - </clipPath>
1375 - <g style="clip-path:url(#SVGID_00000044163849903802845590000005483808105038946735_);">
1376 - <text transform="matrix(1 0 0 1 1642.48 238.87)" class="st67 st68 st69">Code Execution</text>
1377 - <text transform="matrix(1 0 0 1 1870.9301 238.87)" class="st67 st68 st69">T</text>
1378 - <text transform="matrix(1 0 0 1 1885.38 238.87)" class="st67 st68 st69">ool</text>
1379 - </g>
1380 -</g>
1381 -<g>
1382 - <defs>
1383 - <rect id="SVGID_00000091015292727712088220000009902392776322848910_" x="10" y="-315.3" width="2473" height="1264"/>
1384 - </defs>
1385 - <clipPath id="SVGID_00000093872554659356400610000006154570753773668999_">
1386 - <use xlink:href="#SVGID_00000091015292727712088220000009902392776322848910_" style="overflow:visible;"/>
1387 - </clipPath>
1388 - <g style="clip-path:url(#SVGID_00000093872554659356400610000006154570753773668999_);">
1389 - <rect x="2087.2" y="150.6" class="st73" width="330.5" height="154.5"/>
1390 - <rect x="2087.2" y="150.6" class="st74" width="330.5" height="154.5"/>
1391 - </g>
1392 -</g>
1393 -<g>
1394 - <defs>
1395 - <rect id="SVGID_00000152266102049190071170000016197699550400276112_" x="2146.6" y="180.3" width="212.3" height="95.1"/>
1396 - </defs>
1397 - <clipPath id="SVGID_00000065765156003939193360000016040771760165585339_">
1398 - <use xlink:href="#SVGID_00000152266102049190071170000016197699550400276112_" style="overflow:visible;"/>
1399 - </clipPath>
1400 - <g style="clip-path:url(#SVGID_00000065765156003939193360000016040771760165585339_);">
1401 - <text transform="matrix(1 0 0 1 2146.5801 215.11)" class="st67 st68 st69">W</text>
1402 - <text transform="matrix(1 0 0 1 2172.1299 215.11)" class="st67 st68 st69">ork Directory</text>
1403 - <text transform="matrix(1 0 0 1 2190.1499 262.64)" class="st67 st68 st69">work_dir</text>
1404 - </g>
1405 -</g>
1406 -</svg>
docs/res/banner.png
Binary files a/docs/res/banner.png and b/docs/res/banner.png differ
docs/res/banner_high.png
Binary files a/docs/res/banner_high.png and b/docs/res/banner_high.png differ
docs/res/code_exec_jailbreak.png
Binary files a/docs/res/code_exec_jailbreak.png and /dev/null differ
docs/res/david_vid.jpg
Binary files a/docs/res/david_vid.jpg and /dev/null differ
docs/res/dev/devinst-1.png
Binary files a/docs/res/dev/devinst-1.png and b/docs/res/dev/devinst-1.png differ
docs/res/dev/devinst-10.png
Binary files a/docs/res/dev/devinst-10.png and b/docs/res/dev/devinst-10.png differ
docs/res/dev/devinst-11.png
Binary files a/docs/res/dev/devinst-11.png and b/docs/res/dev/devinst-11.png differ
docs/res/dev/devinst-12.png
Binary files a/docs/res/dev/devinst-12.png and b/docs/res/dev/devinst-12.png differ
docs/res/dev/devinst-13.png
Binary files a/docs/res/dev/devinst-13.png and b/docs/res/dev/devinst-13.png differ
docs/res/dev/devinst-14.png
Binary files a/docs/res/dev/devinst-14.png and b/docs/res/dev/devinst-14.png differ
docs/res/dev/devinst-2.png
Binary files a/docs/res/dev/devinst-2.png and b/docs/res/dev/devinst-2.png differ
docs/res/dev/devinst-3.png
Binary files a/docs/res/dev/devinst-3.png and b/docs/res/dev/devinst-3.png differ
docs/res/dev/devinst-4.png
Binary files a/docs/res/dev/devinst-4.png and b/docs/res/dev/devinst-4.png differ
docs/res/dev/devinst-5.png
Binary files a/docs/res/dev/devinst-5.png and b/docs/res/dev/devinst-5.png differ
docs/res/dev/devinst-6.png
Binary files a/docs/res/dev/devinst-6.png and b/docs/res/dev/devinst-6.png differ
docs/res/dev/devinst-7.png
Binary files a/docs/res/dev/devinst-7.png and b/docs/res/dev/devinst-7.png differ
docs/res/dev/devinst-8.png
Binary files a/docs/res/dev/devinst-8.png and b/docs/res/dev/devinst-8.png differ
docs/res/dev/devinst-9.png
Binary files a/docs/res/dev/devinst-9.png and b/docs/res/dev/devinst-9.png differ
docs/res/devguide_vid.png
Binary files a/docs/res/devguide_vid.png and b/docs/res/devguide_vid.png differ
docs/res/easy_ins_vid.png
Binary files a/docs/res/easy_ins_vid.png and b/docs/res/easy_ins_vid.png differ
docs/res/favicon.png
Binary files a/docs/res/favicon.png and b/docs/res/favicon.png differ
docs/res/favicon_round.png
Binary files a/docs/res/favicon_round.png and b/docs/res/favicon_round.png differ
docs/res/flask_link.png
Binary files a/docs/res/flask_link.png and /dev/null differ
docs/res/flow-01.svg deleted
-144
@@ -1,144 +0,0 @@
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2493.12 242.76">
3 - <defs>
4 - <clipPath id="clippath">
5 - <rect x="244.36" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
6 - </clipPath>
7 - <clipPath id="clippath-1">
8 - <rect x="602.88" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
9 - </clipPath>
10 - <clipPath id="clippath-2">
11 - <rect x="1171.11" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
12 - </clipPath>
13 - <clipPath id="clippath-3">
14 - <rect x="1406.59" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
15 - </clipPath>
16 - <clipPath id="clippath-4">
17 - <rect x="1773.44" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
18 - </clipPath>
19 - <clipPath id="clippath-5">
20 - <rect x="2008.92" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
21 - </clipPath>
22 - <clipPath id="clippath-6">
23 - <rect x="2258.74" y="114.63" width="13.5" height="13.5" fill="none" stroke-width="0"/>
24 - </clipPath>
25 - <clipPath id="clippath-7">
26 - <rect x="29.83" y="90" width="136.79" height="62.76" fill="none" stroke-width="0"/>
27 - </clipPath>
28 - <clipPath id="clippath-8">
29 - <rect x="283.16" y="101.14" width="224.03" height="40.49" fill="none" stroke-width="0"/>
30 - </clipPath>
31 - <clipPath id="clippath-9">
32 - <rect x="952.02" y="101.14" width="102.57" height="40.49" fill="none" stroke-width="0"/>
33 - </clipPath>
34 - <clipPath id="clippath-10">
35 - <rect x="1209.91" y="101.14" width="99.87" height="40.49" fill="none" stroke-width="0"/>
36 - </clipPath>
37 - <clipPath id="clippath-11">
38 - <rect x="1445.39" y="101.14" width="232.13" height="40.49" fill="none" stroke-width="0"/>
39 - </clipPath>
40 - <clipPath id="clippath-12">
41 - <rect x="1812.24" y="101.14" width="99.87" height="40.49" fill="none" stroke-width="0"/>
42 - </clipPath>
43 - <clipPath id="clippath-13">
44 - <rect x="2047.72" y="101.14" width="114.71" height="40.49" fill="none" stroke-width="0"/>
45 - </clipPath>
46 - <clipPath id="clippath-14">
47 - <rect x="2278.54" y="79.78" width="190.08" height="77.4" fill="none" stroke-width="0"/>
48 - </clipPath>
49 - <clipPath id="clippath-15">
50 - <rect x="629.03" y="118.01" width="180.84" height="40.49" fill="none" stroke-width="0"/>
51 - </clipPath>
52 - </defs>
53 - <path d="m173.51,121.38h77.6" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
54 - <g clip-path="url(#clippath)">
55 - <polygon points="244.36 114.63 257.86 121.38 244.36 128.13 244.36 114.63" fill="#d3d3d3" stroke-width="0"/>
56 - <path d="m243.69,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
57 - </g>
58 - <path d="m532.03,121.38h77.6" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
59 - <g clip-path="url(#clippath-1)">
60 - <polygon points="602.88 114.63 616.38 121.38 602.88 128.13 602.88 114.63" fill="#d3d3d3" stroke-width="0"/>
61 - <path d="m602.21,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
62 - </g>
63 - <path d="m822.12,121.38h7.03c7.03,0,21.09,0,31.7.07,10.61.07,17.78.21,23.83.33,6.04.12,10.97.21,13.43.26l2.46.05" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
64 - <path d="m1101.11,122.22l6.89-.14c6.89-.14,20.67-.42,31.07-.56,10.4-.14,17.43-.14,23.34-.14h15.46" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
65 - <g clip-path="url(#clippath-2)">
66 - <polygon points="1171.11 114.63 1184.61 121.38 1171.11 128.13 1171.11 114.63" fill="#d3d3d3" stroke-width="0"/>
67 - <path d="m1170.44,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
68 - </g>
69 - <path d="m1335.74,121.38h77.6" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
70 - <g clip-path="url(#clippath-3)">
71 - <polygon points="1406.59 114.63 1420.09 121.38 1406.59 128.13 1406.59 114.63" fill="#d3d3d3" stroke-width="0"/>
72 - <path d="m1405.92,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
73 - </g>
74 - <path d="m1702.59,121.38h77.6" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
75 - <g clip-path="url(#clippath-4)">
76 - <polygon points="1773.44 114.63 1786.94 121.38 1773.44 128.13 1773.44 114.63" fill="#d3d3d3" stroke-width="0"/>
77 - <path d="m1772.77,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
78 - </g>
79 - <path d="m1938.07,121.38h77.6" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
80 - <g clip-path="url(#clippath-5)">
81 - <polygon points="2008.92 114.63 2022.42 121.38 2008.92 128.13 2008.92 114.63" fill="#d3d3d3" stroke-width="0"/>
82 - <path d="m2008.25,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
83 - </g>
84 - <path d="m2187.89,121.38h77.6" fill="none" stroke="#d3d3d3" stroke-width="1.69"/>
85 - <g clip-path="url(#clippath-6)">
86 - <polygon points="2258.74 114.63 2272.24 121.38 2258.74 128.13 2258.74 114.63" fill="#d3d3d3" stroke-width="0"/>
87 - <path d="m2258.07,115.12v-1.58l2.18,1.09-.6,1.21-1.21-.6.3-.6h.67v.49h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm0,1.35v-1.35h1.35v1.35h-1.35Zm1.41,1.25l-1.41.71v-1.95h1.35v.86h-.67l-.3-.6.44-.22.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm1.21-.6l-1.21.6-.6-1.21,1.21-.6.6,1.21Zm.77-1.81l1.42.71-2.2,1.1-.6-1.21.99-.49.3.6-.3.6-.22-.11.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Zm-1.21-.6l1.21.6-.6,1.21-1.21-.6.6-1.21Z" fill="#d3d3d3" stroke-width="0"/>
88 - </g>
89 - <path d="m173.51,121.38c0,1.23-.03,2.45-.09,3.68-.06,1.23-.15,2.45-.27,3.67-.12,1.22-.27,2.44-.45,3.65-.18,1.21-.39,2.42-.63,3.63-.24,1.2-.51,2.4-.81,3.59-.3,1.19-.63,2.37-.98,3.55s-.74,2.34-1.15,3.5c-.41,1.16-.86,2.3-1.32,3.43-.47,1.13-.97,2.26-1.49,3.37-.52,1.11-1.08,2.21-1.66,3.29-.58,1.08-1.18,2.15-1.81,3.2-.63,1.05-1.29,2.09-1.97,3.11-.68,1.02-1.39,2.02-2.12,3.01-.73.99-1.49,1.95-2.26,2.9-.78.95-1.58,1.88-2.4,2.79-.82.91-1.67,1.8-2.54,2.67-.87.87-1.76,1.71-2.67,2.54-.91.82-1.84,1.63-2.79,2.4-.95.78-1.92,1.53-2.9,2.27s-1.99,1.44-3.01,2.12-2.06,1.34-3.11,1.97c-1.05.63-2.12,1.24-3.2,1.81-1.08.58-2.18,1.13-3.29,1.66-1.11.52-2.23,1.02-3.37,1.49-1.13.47-2.28.91-3.43,1.33-1.16.41-2.32.8-3.5,1.15-1.17.36-2.36.68-3.55.98-1.19.3-2.39.57-3.59.81-1.2.24-2.41.45-3.63.63-1.21.18-2.43.33-3.65.45-1.22.12-2.45.21-3.67.27s-2.45.09-3.68.09-2.45-.03-3.68-.09c-1.23-.06-2.45-.15-3.67-.27-1.22-.12-2.44-.27-3.65-.45-1.21-.18-2.42-.39-3.63-.63-1.2-.24-2.4-.51-3.59-.81-1.19-.3-2.37-.63-3.55-.98-1.17-.36-2.34-.74-3.5-1.15-1.16-.41-2.3-.86-3.43-1.33-1.13-.47-2.26-.97-3.37-1.49-1.11-.52-2.21-1.08-3.29-1.66-1.08-.58-2.15-1.18-3.2-1.81-1.05-.63-2.09-1.29-3.11-1.97s-2.02-1.39-3.01-2.12c-.99-.73-1.95-1.49-2.9-2.27-.95-.78-1.88-1.58-2.79-2.4-.91-.82-1.8-1.67-2.67-2.54-.87-.87-1.71-1.76-2.54-2.67-.82-.91-1.63-1.84-2.4-2.79-.78-.95-1.53-1.92-2.26-2.9-.73-.99-1.44-1.99-2.12-3.01-.68-1.02-1.34-2.06-1.97-3.11-.63-1.05-1.24-2.12-1.81-3.2-.58-1.08-1.13-2.18-1.66-3.29-.52-1.11-1.02-2.23-1.49-3.37-.47-1.13-.91-2.28-1.32-3.43-.41-1.16-.8-2.32-1.15-3.5-.36-1.17-.68-2.36-.98-3.55-.3-1.19-.57-2.39-.81-3.59-.24-1.2-.45-2.41-.63-3.63-.18-1.21-.33-2.43-.45-3.65-.12-1.22-.21-2.45-.27-3.67-.06-1.23-.09-2.45-.09-3.68,0-1.23.03-2.45.09-3.68.06-1.23.15-2.45.27-3.67.12-1.22.27-2.44.45-3.65.18-1.21.39-2.42.63-3.63.24-1.2.51-2.4.81-3.59.3-1.19.63-2.37.98-3.55.36-1.17.74-2.34,1.15-3.5.41-1.16.86-2.3,1.32-3.43.47-1.13.97-2.26,1.49-3.37s1.08-2.21,1.66-3.29c.58-1.08,1.18-2.15,1.81-3.2.63-1.05,1.29-2.09,1.97-3.11.68-1.02,1.39-2.02,2.12-3.01.73-.99,1.49-1.95,2.26-2.9.78-.95,1.58-1.88,2.4-2.79.82-.91,1.67-1.8,2.54-2.67.87-.87,1.76-1.71,2.67-2.54s1.84-1.63,2.79-2.4c.95-.78,1.92-1.53,2.9-2.26.99-.73,1.99-1.44,3.01-2.12,1.02-.68,2.06-1.34,3.11-1.97,1.05-.63,2.12-1.24,3.2-1.81s2.18-1.13,3.29-1.66c1.11-.52,2.23-1.02,3.37-1.49,1.13-.47,2.28-.91,3.43-1.33,1.16-.41,2.32-.8,3.5-1.15,1.17-.36,2.36-.68,3.55-.98s2.39-.57,3.59-.81c1.2-.24,2.41-.45,3.63-.63,1.21-.18,2.43-.33,3.65-.45,1.22-.12,2.45-.21,3.67-.27,1.23-.06,2.45-.09,3.68-.09s2.45.03,3.68.09c1.23.06,2.45.15,3.67.27s2.44.27,3.65.45,2.42.39,3.63.63c1.2.24,2.4.51,3.59.81s2.37.63,3.55.98c1.17.36,2.34.74,3.5,1.15,1.16.41,2.3.86,3.43,1.33,1.13.47,2.26.97,3.37,1.49,1.11.52,2.21,1.08,3.29,1.66s2.15,1.18,3.2,1.81c1.05.63,2.09,1.29,3.11,1.97,1.02.68,2.02,1.39,3.01,2.12.99.73,1.95,1.49,2.9,2.26.95.78,1.88,1.58,2.79,2.4.91.82,1.8,1.67,2.67,2.54.87.87,1.71,1.76,2.54,2.67.82.91,1.63,1.84,2.4,2.79.78.95,1.53,1.92,2.26,2.9.73.99,1.44,1.99,2.12,3.01.68,1.02,1.34,2.06,1.97,3.11.63,1.05,1.24,2.12,1.81,3.2.58,1.08,1.13,2.18,1.66,3.29s1.02,2.23,1.49,3.37c.47,1.13.91,2.28,1.32,3.43.41,1.16.8,2.32,1.15,3.5s.68,2.36.98,3.55c.3,1.19.57,2.39.81,3.59.24,1.2.45,2.41.63,3.63.18,1.21.33,2.43.45,3.65.12,1.22.21,2.45.27,3.67.06,1.23.09,2.45.09,3.68Z" fill="#1f2020" stroke-width="0"/>
90 - <path d="m173.51,121.38c0,1.23-.03,2.45-.09,3.68-.06,1.23-.15,2.45-.27,3.67-.12,1.22-.27,2.44-.45,3.65-.18,1.21-.39,2.42-.63,3.63-.24,1.2-.51,2.4-.81,3.59-.3,1.19-.63,2.37-.98,3.55s-.74,2.34-1.15,3.5c-.41,1.16-.86,2.3-1.32,3.43-.47,1.13-.97,2.26-1.49,3.37-.52,1.11-1.08,2.21-1.66,3.29-.58,1.08-1.18,2.15-1.81,3.2-.63,1.05-1.29,2.09-1.97,3.11-.68,1.02-1.39,2.02-2.12,3.01-.73.99-1.49,1.95-2.26,2.9-.78.95-1.58,1.88-2.4,2.79-.82.91-1.67,1.8-2.54,2.67-.87.87-1.76,1.71-2.67,2.54-.91.82-1.84,1.63-2.79,2.4-.95.78-1.92,1.53-2.9,2.27s-1.99,1.44-3.01,2.12-2.06,1.34-3.11,1.97c-1.05.63-2.12,1.24-3.2,1.81-1.08.58-2.18,1.13-3.29,1.66-1.11.52-2.23,1.02-3.37,1.49-1.13.47-2.28.91-3.43,1.33-1.16.41-2.32.8-3.5,1.15-1.17.36-2.36.68-3.55.98-1.19.3-2.39.57-3.59.81-1.2.24-2.41.45-3.63.63-1.21.18-2.43.33-3.65.45-1.22.12-2.45.21-3.67.27s-2.45.09-3.68.09-2.45-.03-3.68-.09c-1.23-.06-2.45-.15-3.67-.27-1.22-.12-2.44-.27-3.65-.45-1.21-.18-2.42-.39-3.63-.63-1.2-.24-2.4-.51-3.59-.81-1.19-.3-2.37-.63-3.55-.98-1.17-.36-2.34-.74-3.5-1.15-1.16-.41-2.3-.86-3.43-1.33-1.13-.47-2.26-.97-3.37-1.49-1.11-.52-2.21-1.08-3.29-1.66-1.08-.58-2.15-1.18-3.2-1.81-1.05-.63-2.09-1.29-3.11-1.97s-2.02-1.39-3.01-2.12c-.99-.73-1.95-1.49-2.9-2.27-.95-.78-1.88-1.58-2.79-2.4-.91-.82-1.8-1.67-2.67-2.54-.87-.87-1.71-1.76-2.54-2.67-.82-.91-1.63-1.84-2.4-2.79-.78-.95-1.53-1.92-2.26-2.9-.73-.99-1.44-1.99-2.12-3.01-.68-1.02-1.34-2.06-1.97-3.11-.63-1.05-1.24-2.12-1.81-3.2-.58-1.08-1.13-2.18-1.66-3.29-.52-1.11-1.02-2.23-1.49-3.37-.47-1.13-.91-2.28-1.32-3.43-.41-1.16-.8-2.32-1.15-3.5-.36-1.17-.68-2.36-.98-3.55-.3-1.19-.57-2.39-.81-3.59-.24-1.2-.45-2.41-.63-3.63-.18-1.21-.33-2.43-.45-3.65-.12-1.22-.21-2.45-.27-3.67-.06-1.23-.09-2.45-.09-3.68,0-1.23.03-2.45.09-3.68.06-1.23.15-2.45.27-3.67.12-1.22.27-2.44.45-3.65.18-1.21.39-2.42.63-3.63.24-1.2.51-2.4.81-3.59.3-1.19.63-2.37.98-3.55.36-1.17.74-2.34,1.15-3.5.41-1.16.86-2.3,1.32-3.43.47-1.13.97-2.26,1.49-3.37s1.08-2.21,1.66-3.29c.58-1.08,1.18-2.15,1.81-3.2.63-1.05,1.29-2.09,1.97-3.11.68-1.02,1.39-2.02,2.12-3.01.73-.99,1.49-1.95,2.26-2.9.78-.95,1.58-1.88,2.4-2.79.82-.91,1.67-1.8,2.54-2.67.87-.87,1.76-1.71,2.67-2.54s1.84-1.63,2.79-2.4c.95-.78,1.92-1.53,2.9-2.26.99-.73,1.99-1.44,3.01-2.12,1.02-.68,2.06-1.34,3.11-1.97,1.05-.63,2.12-1.24,3.2-1.81s2.18-1.13,3.29-1.66c1.11-.52,2.23-1.02,3.37-1.49,1.13-.47,2.28-.91,3.43-1.33,1.16-.41,2.32-.8,3.5-1.15,1.17-.36,2.36-.68,3.55-.98s2.39-.57,3.59-.81c1.2-.24,2.41-.45,3.63-.63,1.21-.18,2.43-.33,3.65-.45,1.22-.12,2.45-.21,3.67-.27,1.23-.06,2.45-.09,3.68-.09s2.45.03,3.68.09c1.23.06,2.45.15,3.67.27s2.44.27,3.65.45,2.42.39,3.63.63c1.2.24,2.4.51,3.59.81s2.37.63,3.55.98c1.17.36,2.34.74,3.5,1.15,1.16.41,2.3.86,3.43,1.33,1.13.47,2.26.97,3.37,1.49,1.11.52,2.21,1.08,3.29,1.66s2.15,1.18,3.2,1.81c1.05.63,2.09,1.29,3.11,1.97,1.02.68,2.02,1.39,3.01,2.12.99.73,1.95,1.49,2.9,2.26.95.78,1.88,1.58,2.79,2.4.91.82,1.8,1.67,2.67,2.54.87.87,1.71,1.76,2.54,2.67.82.91,1.63,1.84,2.4,2.79.78.95,1.53,1.92,2.26,2.9.73.99,1.44,1.99,2.12,3.01.68,1.02,1.34,2.06,1.97,3.11.63,1.05,1.24,2.12,1.81,3.2.58,1.08,1.13,2.18,1.66,3.29s1.02,2.23,1.49,3.37c.47,1.13.91,2.28,1.32,3.43.41,1.16.8,2.32,1.15,3.5s.68,2.36.98,3.55c.3,1.19.57,2.39.81,3.59.24,1.2.45,2.41.63,3.63.18,1.21.33,2.43.45,3.65.12,1.22.21,2.45.27,3.67.06,1.23.09,2.45.09,3.68Z" fill="none" stroke="#ccc" stroke-width="1.69"/>
91 - <g clip-path="url(#clippath-7)">
92 - <text transform="translate(68.49 119.44)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="29.74"><tspan x="0" y="0">User</tspan></text>
93 - <text transform="translate(61.29 142.24)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="29.74"><tspan x="0" y="0">input</tspan></text>
94 - </g>
95 - <path d="m266.29,75.83h257.3c.55,0,1.1.05,1.65.16.54.11,1.07.27,1.58.48.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58-.21.51-.47,1-.78,1.46s-.66.89-1.05,1.28-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78-.51.21-1.04.37-1.58.48-.54.11-1.09.16-1.65.16h-257.3c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78c-.46-.31-.89-.66-1.28-1.05-.39-.39-.74-.82-1.05-1.28-.31-.46-.57-.95-.78-1.46s-.37-1.04-.48-1.58c-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48s1.09-.16,1.65-.16Z" fill="#048" stroke-width="0"/>
96 - <path d="m266.29,75.83h257.3c.55,0,1.1.05,1.65.16.54.11,1.07.27,1.58.48.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58-.21.51-.47,1-.78,1.46s-.66.89-1.05,1.28-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78-.51.21-1.04.37-1.58.48-.54.11-1.09.16-1.65.16h-257.3c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78c-.46-.31-.89-.66-1.28-1.05-.39-.39-.74-.82-1.05-1.28-.31-.46-.57-.95-.78-1.46s-.37-1.04-.48-1.58c-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48s1.09-.16,1.65-.16Z" fill="none" stroke="#000" stroke-width="3.37"/>
97 - <g clip-path="url(#clippath-8)">
98 - <text transform="translate(283.16 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">V</tspan></text>
99 - <text transform="translate(297.28 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">ectorDB Initialize</tspan></text>
100 - </g>
101 - <rect x="934.85" y="52.86" width="137.03" height="137.03" transform="translate(208.05 745.04) rotate(-45)" fill="#048" stroke-width="0"/>
102 - <rect x="934.85" y="52.86" width="137.03" height="137.03" transform="translate(208.05 745.04) rotate(-45)" fill="none" stroke="#000" stroke-width="3.37"/>
103 - <g clip-path="url(#clippath-9)">
104 - <text transform="translate(952.02 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">Planning</tspan></text>
105 - </g>
106 - <path d="m1193.04,75.83h134.26c.55,0,1.1.05,1.65.16s1.07.27,1.58.48c.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58-.21.51-.47,1-.78,1.46s-.66.89-1.05,1.28-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78s-1.04.37-1.58.48c-.54.11-1.09.16-1.65.16h-134.26c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78c-.46-.31-.89-.66-1.28-1.05-.39-.39-.74-.82-1.05-1.28s-.57-.95-.78-1.46c-.21-.51-.37-1.04-.48-1.58-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05s.95-.57,1.46-.78c.51-.21,1.04-.37,1.58-.48.54-.11,1.09-.16,1.65-.16Z" fill="#048" stroke-width="0"/>
107 - <path d="m1193.04,75.83h134.26c.55,0,1.1.05,1.65.16s1.07.27,1.58.48c.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58-.21.51-.47,1-.78,1.46s-.66.89-1.05,1.28-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78s-1.04.37-1.58.48c-.54.11-1.09.16-1.65.16h-134.26c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78c-.46-.31-.89-.66-1.28-1.05-.39-.39-.74-.82-1.05-1.28s-.57-.95-.78-1.46c-.21-.51-.37-1.04-.48-1.58-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05s.95-.57,1.46-.78c.51-.21,1.04-.37,1.58-.48.54-.11,1.09-.16,1.65-.16Z" fill="none" stroke="#000" stroke-width="3.37"/>
108 - <g clip-path="url(#clippath-10)">
109 - <text transform="translate(1209.91 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">T</tspan></text>
110 - <text transform="translate(1222.22 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">ool Use</tspan></text>
111 - </g>
112 - <path d="m1428.52,75.83h265.63c.55,0,1.1.05,1.65.16.54.11,1.07.27,1.58.48.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58s-.47,1-.78,1.46c-.31.46-.66.89-1.05,1.28s-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78-.51.21-1.04.37-1.58.48-.54.11-1.09.16-1.65.16h-265.63c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48-.51-.21-1-.47-1.46-.78-.46-.31-.89-.66-1.28-1.05s-.74-.82-1.05-1.28c-.31-.46-.57-.95-.78-1.46-.21-.51-.37-1.04-.48-1.58-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48s1.09-.16,1.65-.16Z" fill="#048" stroke-width="0"/>
113 - <path d="m1428.52,75.83h265.63c.55,0,1.1.05,1.65.16.54.11,1.07.27,1.58.48.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58s-.47,1-.78,1.46c-.31.46-.66.89-1.05,1.28s-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78-.51.21-1.04.37-1.58.48-.54.11-1.09.16-1.65.16h-265.63c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48-.51-.21-1-.47-1.46-.78-.46-.31-.89-.66-1.28-1.05s-.74-.82-1.05-1.28c-.31-.46-.57-.95-.78-1.46-.21-.51-.37-1.04-.48-1.58-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48s1.09-.16,1.65-.16Z" fill="none" stroke="#000" stroke-width="3.37"/>
114 - <g clip-path="url(#clippath-11)">
115 - <text transform="translate(1445.39 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">Sub-agent Creation</tspan></text>
116 - </g>
117 - <path d="m1795.37,75.83h134.26c.55,0,1.1.05,1.65.16.54.11,1.07.27,1.58.48.51.21,1,.47,1.46.78s.89.66,1.28,1.05c.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58-.21.51-.47,1-.78,1.46s-.66.89-1.05,1.28-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78s-1.04.37-1.58.48c-.54.11-1.09.16-1.65.16h-134.26c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78-.89-.66-1.28-1.05-.74-.82-1.05-1.28-.57-.95-.78-1.46c-.21-.51-.37-1.04-.48-1.58-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48.54-.11,1.09-.16,1.65-.16Z" fill="#048" stroke-width="0"/>
118 - <path d="m1795.37,75.83h134.26c.55,0,1.1.05,1.65.16.54.11,1.07.27,1.58.48.51.21,1,.47,1.46.78s.89.66,1.28,1.05c.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58-.21.51-.47,1-.78,1.46s-.66.89-1.05,1.28-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78s-1.04.37-1.58.48c-.54.11-1.09.16-1.65.16h-134.26c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78-.89-.66-1.28-1.05-.74-.82-1.05-1.28-.57-.95-.78-1.46c-.21-.51-.37-1.04-.48-1.58-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48.54-.11,1.09-.16,1.65-.16Z" fill="none" stroke="#000" stroke-width="3.37"/>
119 - <g clip-path="url(#clippath-12)">
120 - <text transform="translate(1812.24 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">T</tspan></text>
121 - <text transform="translate(1824.55 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">ool Use</tspan></text>
122 - </g>
123 - <path d="m2030.85,75.83h148.6c.55,0,1.1.05,1.65.16s1.07.27,1.58.48c.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58s-.47,1-.78,1.46c-.31.46-.66.89-1.05,1.28s-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78s-1.04.37-1.58.48c-.54.11-1.09.16-1.65.16h-148.6c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78c-.46-.31-.89-.66-1.28-1.05s-.74-.82-1.05-1.28c-.31-.46-.57-.95-.78-1.46s-.37-1.04-.48-1.58c-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48.54-.11,1.09-.16,1.65-.16Z" fill="#048" stroke-width="0"/>
124 - <path d="m2030.85,75.83h148.6c.55,0,1.1.05,1.65.16s1.07.27,1.58.48c.51.21,1,.47,1.46.78.46.31.89.66,1.28,1.05.39.39.74.82,1.05,1.28.31.46.57.95.78,1.46.21.51.37,1.04.48,1.58.11.54.16,1.09.16,1.65v74.23c0,.55-.05,1.1-.16,1.65-.11.54-.27,1.07-.48,1.58s-.47,1-.78,1.46c-.31.46-.66.89-1.05,1.28s-.82.74-1.28,1.05c-.46.31-.95.57-1.46.78s-1.04.37-1.58.48c-.54.11-1.09.16-1.65.16h-148.6c-.55,0-1.1-.05-1.65-.16-.54-.11-1.07-.27-1.58-.48s-1-.47-1.46-.78c-.46-.31-.89-.66-1.28-1.05s-.74-.82-1.05-1.28c-.31-.46-.57-.95-.78-1.46s-.37-1.04-.48-1.58c-.11-.54-.16-1.09-.16-1.65v-74.23c0-.55.05-1.1.16-1.65.11-.54.27-1.07.48-1.58.21-.51.47-1,.78-1.46.31-.46.66-.89,1.05-1.28.39-.39.82-.74,1.28-1.05.46-.31.95-.57,1.46-.78.51-.21,1.04-.37,1.58-.48.54-.11,1.09-.16,1.65-.16Z" fill="none" stroke="#000" stroke-width="3.37"/>
125 - <g clip-path="url(#clippath-13)">
126 - <text transform="translate(2047.72 130.83)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">Feedback</tspan></text>
127 - </g>
128 - <g>
129 - <path d="m2428.99,121.38c0,1.24-.03,2.48-.09,3.72-.06,1.24-.15,2.47-.27,3.71-.12,1.23-.27,2.46-.46,3.69-.18,1.23-.39,2.45-.64,3.66-.24,1.22-.51,2.43-.81,3.63-.3,1.2-.63,2.4-.99,3.58-.36,1.19-.75,2.36-1.17,3.53-.42,1.17-.86,2.32-1.34,3.47-.47,1.15-.98,2.28-1.51,3.4-.53,1.12-1.09,2.23-1.67,3.32-.58,1.09-1.2,2.17-1.83,3.24-.64,1.06-1.3,2.11-1.99,3.14-.69,1.03-1.4,2.04-2.14,3.04s-1.5,1.97-2.29,2.93c-.79.96-1.6,1.9-2.43,2.82-.83.92-1.69,1.82-2.56,2.69-.88.88-1.77,1.73-2.69,2.56-.92.83-1.86,1.64-2.82,2.43s-1.94,1.55-2.93,2.29c-1,.74-2.01,1.45-3.04,2.14-1.03.69-2.08,1.35-3.14,1.99-1.06.64-2.14,1.25-3.24,1.83s-2.2,1.14-3.32,1.67-2.25,1.03-3.4,1.51c-1.15.47-2.3.92-3.47,1.34-1.17.42-2.34.81-3.53,1.17-1.19.36-2.38.69-3.58.99s-2.41.57-3.63.81c-1.22.24-2.44.45-3.66.64-1.23.18-2.46.33-3.69.46-1.23.12-2.47.21-3.71.27-1.24.06-2.48.09-3.72.09s-2.48-.03-3.72-.09c-1.24-.06-2.47-.15-3.71-.27-1.23-.12-2.46-.27-3.69-.46-1.23-.18-2.45-.39-3.66-.64-1.22-.24-2.43-.51-3.63-.81-1.2-.3-2.4-.63-3.58-.99s-2.36-.75-3.53-1.17c-1.17-.42-2.32-.86-3.47-1.34-1.15-.47-2.28-.98-3.4-1.51s-2.23-1.09-3.32-1.67c-1.09-.58-2.17-1.2-3.24-1.83s-2.11-1.3-3.14-1.99c-1.03-.69-2.04-1.4-3.04-2.14-1-.74-1.97-1.5-2.93-2.29-.96-.79-1.9-1.6-2.82-2.43-.92-.83-1.82-1.69-2.69-2.56-.88-.88-1.73-1.77-2.56-2.69-.83-.92-1.64-1.86-2.43-2.82-.79-.96-1.55-1.94-2.29-2.93-.74-1-1.45-2.01-2.14-3.04-.69-1.03-1.35-2.08-1.99-3.14s-1.25-2.14-1.83-3.24c-.58-1.09-1.14-2.2-1.67-3.32-.53-1.12-1.03-2.25-1.51-3.4-.47-1.15-.92-2.3-1.34-3.47-.42-1.17-.81-2.34-1.17-3.53-.36-1.19-.69-2.38-.99-3.58s-.57-2.41-.81-3.63c-.24-1.22-.45-2.44-.64-3.66-.18-1.23-.33-2.46-.46-3.69-.12-1.23-.21-2.47-.27-3.71-.06-1.24-.09-2.48-.09-3.72s.03-2.48.09-3.72c.06-1.24.15-2.47.27-3.71.12-1.23.27-2.46.46-3.69.18-1.23.39-2.45.64-3.66s.51-2.43.81-3.63.63-2.4.99-3.58c.36-1.19.75-2.36,1.17-3.53.42-1.17.86-2.32,1.34-3.47.47-1.15.98-2.28,1.51-3.4.53-1.12,1.09-2.23,1.67-3.32.58-1.09,1.2-2.17,1.83-3.24.64-1.06,1.3-2.11,1.99-3.14.69-1.03,1.4-2.04,2.14-3.04.74-1,1.5-1.97,2.29-2.93.79-.96,1.6-1.9,2.43-2.82.83-.92,1.69-1.82,2.56-2.69.88-.88,1.77-1.73,2.69-2.56.92-.83,1.86-1.64,2.82-2.43.96-.79,1.94-1.55,2.93-2.29,1-.74,2.01-1.45,3.04-2.14,1.03-.69,2.08-1.35,3.14-1.99s2.14-1.25,3.24-1.83,2.2-1.14,3.32-1.67c1.12-.53,2.25-1.03,3.4-1.51,1.15-.47,2.3-.92,3.47-1.34s2.34-.81,3.53-1.17,2.38-.69,3.58-.99c1.2-.3,2.41-.57,3.63-.81,1.22-.24,2.44-.45,3.66-.64,1.23-.18,2.46-.33,3.69-.46,1.23-.12,2.47-.21,3.71-.27,1.24-.06,2.48-.09,3.72-.09s2.48.03,3.72.09c1.24.06,2.48.15,3.71.27,1.23.12,2.46.27,3.69.46s2.45.39,3.66.64c1.22.24,2.43.51,3.63.81,1.2.3,2.4.63,3.58.99,1.19.36,2.36.75,3.53,1.17,1.17.42,2.32.86,3.47,1.34,1.15.47,2.28.98,3.4,1.51,1.12.53,2.23,1.09,3.32,1.67,1.09.58,2.17,1.2,3.24,1.83,1.06.64,2.11,1.3,3.14,1.99,1.03.69,2.04,1.4,3.04,2.14,1,.74,1.97,1.5,2.93,2.29.96.79,1.9,1.6,2.82,2.43.92.83,1.82,1.69,2.69,2.56.88.88,1.73,1.77,2.56,2.69.83.92,1.64,1.86,2.43,2.82.79.96,1.55,1.94,2.29,2.93s1.45,2.01,2.14,3.04c.69,1.03,1.35,2.08,1.99,3.14.64,1.06,1.25,2.14,1.83,3.24.58,1.09,1.14,2.2,1.67,3.32.53,1.12,1.03,2.25,1.51,3.4.47,1.15.92,2.3,1.34,3.47.42,1.17.81,2.34,1.17,3.53.36,1.19.69,2.38.99,3.58.3,1.2.57,2.41.81,3.63.24,1.22.45,2.44.64,3.66.18,1.23.33,2.46.46,3.69.12,1.23.21,2.47.27,3.71.06,1.24.09,2.48.09,3.72Z" fill="#1f2020" stroke-width="0"/>
130 - <path d="m2428.99,121.38c0,1.24-.03,2.48-.09,3.72-.06,1.24-.15,2.47-.27,3.71-.12,1.23-.27,2.46-.46,3.69-.18,1.23-.39,2.45-.64,3.66-.24,1.22-.51,2.43-.81,3.63-.3,1.2-.63,2.4-.99,3.58-.36,1.19-.75,2.36-1.17,3.53-.42,1.17-.86,2.32-1.34,3.47-.47,1.15-.98,2.28-1.51,3.4-.53,1.12-1.09,2.23-1.67,3.32-.58,1.09-1.2,2.17-1.83,3.24-.64,1.06-1.3,2.11-1.99,3.14-.69,1.03-1.4,2.04-2.14,3.04s-1.5,1.97-2.29,2.93c-.79.96-1.6,1.9-2.43,2.82-.83.92-1.69,1.82-2.56,2.69-.88.88-1.77,1.73-2.69,2.56-.92.83-1.86,1.64-2.82,2.43s-1.94,1.55-2.93,2.29c-1,.74-2.01,1.45-3.04,2.14-1.03.69-2.08,1.35-3.14,1.99-1.06.64-2.14,1.25-3.24,1.83s-2.2,1.14-3.32,1.67-2.25,1.03-3.4,1.51c-1.15.47-2.3.92-3.47,1.34-1.17.42-2.34.81-3.53,1.17-1.19.36-2.38.69-3.58.99s-2.41.57-3.63.81c-1.22.24-2.44.45-3.66.64-1.23.18-2.46.33-3.69.46-1.23.12-2.47.21-3.71.27-1.24.06-2.48.09-3.72.09s-2.48-.03-3.72-.09c-1.24-.06-2.47-.15-3.71-.27-1.23-.12-2.46-.27-3.69-.46-1.23-.18-2.45-.39-3.66-.64-1.22-.24-2.43-.51-3.63-.81-1.2-.3-2.4-.63-3.58-.99s-2.36-.75-3.53-1.17c-1.17-.42-2.32-.86-3.47-1.34-1.15-.47-2.28-.98-3.4-1.51s-2.23-1.09-3.32-1.67c-1.09-.58-2.17-1.2-3.24-1.83s-2.11-1.3-3.14-1.99c-1.03-.69-2.04-1.4-3.04-2.14-1-.74-1.97-1.5-2.93-2.29-.96-.79-1.9-1.6-2.82-2.43-.92-.83-1.82-1.69-2.69-2.56-.88-.88-1.73-1.77-2.56-2.69-.83-.92-1.64-1.86-2.43-2.82-.79-.96-1.55-1.94-2.29-2.93-.74-1-1.45-2.01-2.14-3.04-.69-1.03-1.35-2.08-1.99-3.14s-1.25-2.14-1.83-3.24c-.58-1.09-1.14-2.2-1.67-3.32-.53-1.12-1.03-2.25-1.51-3.4-.47-1.15-.92-2.3-1.34-3.47-.42-1.17-.81-2.34-1.17-3.53-.36-1.19-.69-2.38-.99-3.58s-.57-2.41-.81-3.63c-.24-1.22-.45-2.44-.64-3.66-.18-1.23-.33-2.46-.46-3.69-.12-1.23-.21-2.47-.27-3.71-.06-1.24-.09-2.48-.09-3.72s.03-2.48.09-3.72c.06-1.24.15-2.47.27-3.71.12-1.23.27-2.46.46-3.69.18-1.23.39-2.45.64-3.66s.51-2.43.81-3.63.63-2.4.99-3.58c.36-1.19.75-2.36,1.17-3.53.42-1.17.86-2.32,1.34-3.47.47-1.15.98-2.28,1.51-3.4.53-1.12,1.09-2.23,1.67-3.32.58-1.09,1.2-2.17,1.83-3.24.64-1.06,1.3-2.11,1.99-3.14.69-1.03,1.4-2.04,2.14-3.04.74-1,1.5-1.97,2.29-2.93.79-.96,1.6-1.9,2.43-2.82.83-.92,1.69-1.82,2.56-2.69.88-.88,1.77-1.73,2.69-2.56.92-.83,1.86-1.64,2.82-2.43.96-.79,1.94-1.55,2.93-2.29,1-.74,2.01-1.45,3.04-2.14,1.03-.69,2.08-1.35,3.14-1.99s2.14-1.25,3.24-1.83,2.2-1.14,3.32-1.67c1.12-.53,2.25-1.03,3.4-1.51,1.15-.47,2.3-.92,3.47-1.34s2.34-.81,3.53-1.17,2.38-.69,3.58-.99c1.2-.3,2.41-.57,3.63-.81,1.22-.24,2.44-.45,3.66-.64,1.23-.18,2.46-.33,3.69-.46,1.23-.12,2.47-.21,3.71-.27,1.24-.06,2.48-.09,3.72-.09s2.48.03,3.72.09c1.24.06,2.48.15,3.71.27,1.23.12,2.46.27,3.69.46s2.45.39,3.66.64c1.22.24,2.43.51,3.63.81,1.2.3,2.4.63,3.58.99,1.19.36,2.36.75,3.53,1.17,1.17.42,2.32.86,3.47,1.34,1.15.47,2.28.98,3.4,1.51,1.12.53,2.23,1.09,3.32,1.67,1.09.58,2.17,1.2,3.24,1.83,1.06.64,2.11,1.3,3.14,1.99,1.03.69,2.04,1.4,3.04,2.14,1,.74,1.97,1.5,2.93,2.29.96.79,1.9,1.6,2.82,2.43.92.83,1.82,1.69,2.69,2.56.88.88,1.73,1.77,2.56,2.69.83.92,1.64,1.86,2.43,2.82.79.96,1.55,1.94,2.29,2.93s1.45,2.01,2.14,3.04c.69,1.03,1.35,2.08,1.99,3.14.64,1.06,1.25,2.14,1.83,3.24.58,1.09,1.14,2.2,1.67,3.32.53,1.12,1.03,2.25,1.51,3.4.47,1.15.92,2.3,1.34,3.47.42,1.17.81,2.34,1.17,3.53.36,1.19.69,2.38.99,3.58.3,1.2.57,2.41.81,3.63.24,1.22.45,2.44.64,3.66.18,1.23.33,2.46.46,3.69.12,1.23.21,2.47.27,3.71.06,1.24.09,2.48.09,3.72Z" fill="none" stroke="#ccc" stroke-width="1.69"/>
131 - </g>
132 - <g clip-path="url(#clippath-14)">
133 - <text transform="translate(2324.57 117.26)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="29.93"><tspan x="0" y="0">User</tspan></text>
134 - <text transform="translate(2292.62 141.1)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="29.93"><tspan x="0" y="0">Response</tspan></text>
135 - </g>
136 - <g>
137 - <path d="m616.38,78.07c0,.34.04.68.13,1.02.08.34.21.68.37,1.02.17.34.37.68.62,1.01s.54.67.86,1.01c.33.33.7.67,1.11,1,.41.33.86.66,1.35.98.49.33,1.02.65,1.58.97.57.32,1.17.64,1.82.95.64.31,1.33.63,2.05.93.72.31,1.48.61,2.27.91.79.3,1.62.6,2.49.89.87.29,1.77.58,2.7.86.94.28,1.9.56,2.91.84,1,.27,2.04.54,3.11.81,1.07.26,2.17.52,3.3.77,1.13.25,2.29.5,3.48.74,1.19.24,2.41.48,3.66.7,1.25.23,2.52.45,3.82.67,1.3.22,2.63.43,3.98.63,1.35.2,2.73.4,4.13.59,1.4.19,2.82.37,4.27.55,1.44.18,2.91.34,4.39.5,1.48.16,2.99.31,4.51.46,1.52.15,3.06.28,4.62.41,1.56.13,3.13.25,4.71.37,1.58.11,3.18.22,4.79.32,1.61.1,3.23.19,4.87.27,1.63.08,3.27.16,4.93.22,1.65.07,3.31.12,4.97.17,1.67.05,3.34.09,5.01.13,1.68.03,3.35.06,5.03.08,1.68.02,3.36.03,5.05.03s3.37,0,5.05-.03c1.68-.02,3.36-.04,5.03-.08s3.35-.08,5.01-.13c1.67-.05,3.32-.11,4.97-.17,1.65-.07,3.29-.14,4.93-.22,1.63-.08,3.25-.17,4.87-.27,1.61-.1,3.21-.21,4.79-.32,1.58-.11,3.15-.24,4.71-.37,1.56-.13,3.09-.27,4.62-.41,1.52-.15,3.02-.3,4.51-.46,1.48-.16,2.95-.33,4.39-.5,1.44-.18,2.87-.36,4.27-.55,1.4-.19,2.78-.39,4.13-.59,1.35-.2,2.68-.41,3.98-.63,1.3-.22,2.58-.44,3.82-.67s2.47-.46,3.66-.7c1.19-.24,2.35-.49,3.48-.74,1.13-.25,2.23-.51,3.3-.77,1.07-.26,2.1-.53,3.11-.81,1-.27,1.97-.55,2.91-.84s1.84-.57,2.7-.86c.87-.29,1.7-.59,2.49-.89.79-.3,1.55-.6,2.27-.91.72-.31,1.4-.62,2.05-.93.64-.31,1.25-.63,1.82-.95.57-.32,1.1-.64,1.58-.97.49-.33.94-.65,1.35-.98.41-.33.78-.66,1.11-1,.33-.33.62-.67.86-1.01.25-.34.45-.68.62-1.01.17-.34.29-.68.37-1.02.08-.34.12-.68.13-1.02,0-.34-.04-.68-.13-1.02-.08-.34-.21-.68-.37-1.02-.17-.34-.37-.68-.62-1.01-.25-.34-.54-.67-.86-1.01-.33-.33-.7-.67-1.11-1-.41-.33-.86-.66-1.35-.98s-1.02-.65-1.58-.97-1.17-.64-1.82-.95-1.33-.63-2.05-.93-1.48-.61-2.27-.91c-.79-.3-1.62-.6-2.49-.89-.87-.29-1.77-.58-2.7-.86-.94-.28-1.9-.56-2.91-.84s-2.04-.54-3.11-.81c-1.07-.26-2.17-.52-3.3-.77-1.13-.25-2.29-.5-3.48-.74-1.19-.24-2.41-.48-3.66-.7-1.25-.23-2.52-.45-3.82-.67-1.3-.22-2.63-.43-3.98-.63-1.35-.2-2.73-.4-4.13-.59-1.4-.19-2.82-.37-4.27-.55-1.44-.18-2.91-.34-4.39-.5-1.48-.16-2.99-.31-4.51-.46-1.52-.15-3.06-.28-4.62-.41-1.56-.13-3.13-.25-4.71-.37-1.58-.11-3.18-.22-4.79-.32-1.61-.1-3.23-.19-4.87-.27-1.63-.08-3.27-.16-4.93-.22-1.65-.07-3.31-.12-4.97-.17-1.67-.05-3.34-.09-5.01-.13s-3.35-.06-5.03-.08c-1.68-.02-3.36-.03-5.05-.03s-3.37,0-5.05.03c-1.68.02-3.36.04-5.03.08-1.68.03-3.35.08-5.01.13-1.66.05-3.32.11-4.97.17-1.65.07-3.29.14-4.93.22-1.63.08-3.25.17-4.87.27-1.61.1-3.21.21-4.79.32-1.58.11-3.15.24-4.71.37-1.56.13-3.09.27-4.62.41-1.52.15-3.02.3-4.51.46s-2.95.33-4.39.5c-1.44.18-2.87.36-4.27.55-1.4.19-2.78.39-4.13.59-1.35.2-2.68.41-3.98.63-1.3.22-2.58.44-3.82.67-1.25.23-2.47.46-3.66.7-1.19.24-2.35.49-3.48.74-1.13.25-2.23.51-3.3.77s-2.1.53-3.11.81-1.97.55-2.91.84c-.94.28-1.84.57-2.7.86-.87.29-1.7.59-2.49.89-.79.3-1.55.6-2.27.91-.72.31-1.4.62-2.05.93s-1.25.63-1.82.95c-.57.32-1.1.64-1.58.97s-.94.65-1.35.98c-.41.33-.78.66-1.11,1-.33.33-.62.67-.86,1.01-.25.34-.45.68-.62,1.01-.17.34-.29.68-.37,1.02-.08.34-.12.68-.13,1.02v86.62c0,.34.04.68.13,1.02.08.34.21.68.37,1.02s.37.68.62,1.01c.25.34.54.67.86,1.01.33.33.7.67,1.11,1,.41.33.86.66,1.35.98.49.33,1.02.65,1.58.97.57.32,1.17.64,1.82.95s1.33.63,2.05.93c.72.31,1.48.61,2.27.91.79.3,1.62.6,2.49.89.87.29,1.77.58,2.7.86.94.28,1.9.56,2.91.84,1,.27,2.04.54,3.11.81,1.07.26,2.17.52,3.3.77,1.13.25,2.29.5,3.48.74,1.19.24,2.41.48,3.66.7s2.52.45,3.82.67c1.3.22,2.63.43,3.98.63s2.73.4,4.13.59c1.4.19,2.82.37,4.27.55,1.44.18,2.91.34,4.39.5s2.99.31,4.51.46c1.52.15,3.06.28,4.62.41,1.56.13,3.13.25,4.71.37,1.58.11,3.18.22,4.79.32,1.61.1,3.23.19,4.87.27,1.63.08,3.27.16,4.93.22,1.65.07,3.31.12,4.97.17,1.67.05,3.34.09,5.01.13,1.68.03,3.35.06,5.03.08,1.68.02,3.36.03,5.05.03s3.37,0,5.05-.03c1.68-.02,3.36-.04,5.03-.08,1.68-.03,3.35-.08,5.01-.13,1.66-.05,3.32-.11,4.97-.17,1.65-.07,3.29-.14,4.93-.22,1.63-.08,3.25-.17,4.87-.27,1.61-.1,3.21-.21,4.79-.32,1.58-.11,3.15-.24,4.71-.37,1.56-.13,3.09-.27,4.62-.41,1.52-.15,3.02-.3,4.51-.46,1.48-.16,2.95-.33,4.39-.5,1.44-.18,2.87-.36,4.27-.55,1.4-.19,2.78-.39,4.13-.59,1.35-.2,2.68-.41,3.98-.63,1.3-.22,2.58-.44,3.82-.67s2.47-.46,3.66-.7c1.19-.24,2.35-.49,3.48-.74,1.13-.25,2.23-.51,3.3-.77,1.07-.26,2.1-.53,3.11-.81,1-.27,1.97-.55,2.91-.84.94-.28,1.84-.57,2.7-.86.87-.29,1.7-.59,2.49-.89.79-.3,1.55-.6,2.27-.91.72-.31,1.4-.62,2.05-.93s1.25-.63,1.82-.95c.57-.32,1.1-.64,1.58-.97s.94-.65,1.35-.98c.41-.33.78-.66,1.11-1,.33-.33.62-.67.86-1.01.25-.34.45-.68.62-1.01.17-.34.29-.68.37-1.02.08-.34.12-.68.13-1.02v-86.62" fill="#048" stroke-width="0"/>
138 - <path d="m616.38,78.07c0,.34.04.68.13,1.02.08.34.21.68.37,1.02.17.34.37.68.62,1.01s.54.67.86,1.01c.33.33.7.67,1.11,1,.41.33.86.66,1.35.98.49.33,1.02.65,1.58.97.57.32,1.17.64,1.82.95.64.31,1.33.63,2.05.93.72.31,1.48.61,2.27.91.79.3,1.62.6,2.49.89.87.29,1.77.58,2.7.86.94.28,1.9.56,2.91.84,1,.27,2.04.54,3.11.81,1.07.26,2.17.52,3.3.77,1.13.25,2.29.5,3.48.74,1.19.24,2.41.48,3.66.7,1.25.23,2.52.45,3.82.67,1.3.22,2.63.43,3.98.63,1.35.2,2.73.4,4.13.59,1.4.19,2.82.37,4.27.55,1.44.18,2.91.34,4.39.5,1.48.16,2.99.31,4.51.46,1.52.15,3.06.28,4.62.41,1.56.13,3.13.25,4.71.37,1.58.11,3.18.22,4.79.32,1.61.1,3.23.19,4.87.27,1.63.08,3.27.16,4.93.22,1.65.07,3.31.12,4.97.17,1.67.05,3.34.09,5.01.13,1.68.03,3.35.06,5.03.08,1.68.02,3.36.03,5.05.03s3.37,0,5.05-.03c1.68-.02,3.36-.04,5.03-.08s3.35-.08,5.01-.13c1.67-.05,3.32-.11,4.97-.17,1.65-.07,3.29-.14,4.93-.22,1.63-.08,3.25-.17,4.87-.27,1.61-.1,3.21-.21,4.79-.32,1.58-.11,3.15-.24,4.71-.37,1.56-.13,3.09-.27,4.62-.41,1.52-.15,3.02-.3,4.51-.46,1.48-.16,2.95-.33,4.39-.5,1.44-.18,2.87-.36,4.27-.55,1.4-.19,2.78-.39,4.13-.59,1.35-.2,2.68-.41,3.98-.63,1.3-.22,2.58-.44,3.82-.67s2.47-.46,3.66-.7c1.19-.24,2.35-.49,3.48-.74,1.13-.25,2.23-.51,3.3-.77,1.07-.26,2.1-.53,3.11-.81,1-.27,1.97-.55,2.91-.84s1.84-.57,2.7-.86c.87-.29,1.7-.59,2.49-.89.79-.3,1.55-.6,2.27-.91.72-.31,1.4-.62,2.05-.93.64-.31,1.25-.63,1.82-.95.57-.32,1.1-.64,1.58-.97.49-.33.94-.65,1.35-.98.41-.33.78-.66,1.11-1,.33-.33.62-.67.86-1.01.25-.34.45-.68.62-1.01.17-.34.29-.68.37-1.02.08-.34.12-.68.13-1.02,0-.34-.04-.68-.13-1.02-.08-.34-.21-.68-.37-1.02-.17-.34-.37-.68-.62-1.01-.25-.34-.54-.67-.86-1.01-.33-.33-.7-.67-1.11-1-.41-.33-.86-.66-1.35-.98s-1.02-.65-1.58-.97-1.17-.64-1.82-.95-1.33-.63-2.05-.93-1.48-.61-2.27-.91c-.79-.3-1.62-.6-2.49-.89-.87-.29-1.77-.58-2.7-.86-.94-.28-1.9-.56-2.91-.84s-2.04-.54-3.11-.81c-1.07-.26-2.17-.52-3.3-.77-1.13-.25-2.29-.5-3.48-.74-1.19-.24-2.41-.48-3.66-.7-1.25-.23-2.52-.45-3.82-.67-1.3-.22-2.63-.43-3.98-.63-1.35-.2-2.73-.4-4.13-.59-1.4-.19-2.82-.37-4.27-.55-1.44-.18-2.91-.34-4.39-.5-1.48-.16-2.99-.31-4.51-.46-1.52-.15-3.06-.28-4.62-.41-1.56-.13-3.13-.25-4.71-.37-1.58-.11-3.18-.22-4.79-.32-1.61-.1-3.23-.19-4.87-.27-1.63-.08-3.27-.16-4.93-.22-1.65-.07-3.31-.12-4.97-.17-1.67-.05-3.34-.09-5.01-.13s-3.35-.06-5.03-.08c-1.68-.02-3.36-.03-5.05-.03s-3.37,0-5.05.03c-1.68.02-3.36.04-5.03.08-1.68.03-3.35.08-5.01.13-1.66.05-3.32.11-4.97.17-1.65.07-3.29.14-4.93.22-1.63.08-3.25.17-4.87.27-1.61.1-3.21.21-4.79.32-1.58.11-3.15.24-4.71.37-1.56.13-3.09.27-4.62.41-1.52.15-3.02.3-4.51.46s-2.95.33-4.39.5c-1.44.18-2.87.36-4.27.55-1.4.19-2.78.39-4.13.59-1.35.2-2.68.41-3.98.63-1.3.22-2.58.44-3.82.67-1.25.23-2.47.46-3.66.7-1.19.24-2.35.49-3.48.74-1.13.25-2.23.51-3.3.77s-2.1.53-3.11.81-1.97.55-2.91.84c-.94.28-1.84.57-2.7.86-.87.29-1.7.59-2.49.89-.79.3-1.55.6-2.27.91-.72.31-1.4.62-2.05.93s-1.25.63-1.82.95c-.57.32-1.1.64-1.58.97s-.94.65-1.35.98c-.41.33-.78.66-1.11,1-.33.33-.62.67-.86,1.01-.25.34-.45.68-.62,1.01-.17.34-.29.68-.37,1.02-.08.34-.12.68-.13,1.02v86.62c0,.34.04.68.13,1.02.08.34.21.68.37,1.02s.37.68.62,1.01c.25.34.54.67.86,1.01.33.33.7.67,1.11,1,.41.33.86.66,1.35.98.49.33,1.02.65,1.58.97.57.32,1.17.64,1.82.95s1.33.63,2.05.93c.72.31,1.48.61,2.27.91.79.3,1.62.6,2.49.89.87.29,1.77.58,2.7.86.94.28,1.9.56,2.91.84,1,.27,2.04.54,3.11.81,1.07.26,2.17.52,3.3.77,1.13.25,2.29.5,3.48.74,1.19.24,2.41.48,3.66.7s2.52.45,3.82.67c1.3.22,2.63.43,3.98.63s2.73.4,4.13.59c1.4.19,2.82.37,4.27.55,1.44.18,2.91.34,4.39.5s2.99.31,4.51.46c1.52.15,3.06.28,4.62.41,1.56.13,3.13.25,4.71.37,1.58.11,3.18.22,4.79.32,1.61.1,3.23.19,4.87.27,1.63.08,3.27.16,4.93.22,1.65.07,3.31.12,4.97.17,1.67.05,3.34.09,5.01.13,1.68.03,3.35.06,5.03.08,1.68.02,3.36.03,5.05.03s3.37,0,5.05-.03c1.68-.02,3.36-.04,5.03-.08,1.68-.03,3.35-.08,5.01-.13,1.66-.05,3.32-.11,4.97-.17,1.65-.07,3.29-.14,4.93-.22,1.63-.08,3.25-.17,4.87-.27,1.61-.1,3.21-.21,4.79-.32,1.58-.11,3.15-.24,4.71-.37,1.56-.13,3.09-.27,4.62-.41,1.52-.15,3.02-.3,4.51-.46,1.48-.16,2.95-.33,4.39-.5,1.44-.18,2.87-.36,4.27-.55,1.4-.19,2.78-.39,4.13-.59,1.35-.2,2.68-.41,3.98-.63,1.3-.22,2.58-.44,3.82-.67s2.47-.46,3.66-.7c1.19-.24,2.35-.49,3.48-.74,1.13-.25,2.23-.51,3.3-.77,1.07-.26,2.1-.53,3.11-.81,1-.27,1.97-.55,2.91-.84.94-.28,1.84-.57,2.7-.86.87-.29,1.7-.59,2.49-.89.79-.3,1.55-.6,2.27-.91.72-.31,1.4-.62,2.05-.93s1.25-.63,1.82-.95c.57-.32,1.1-.64,1.58-.97s.94-.65,1.35-.98c.41-.33.78-.66,1.11-1,.33-.33.62-.67.86-1.01.25-.34.45-.68.62-1.01.17-.34.29-.68.37-1.02.08-.34.12-.68.13-1.02v-86.62" fill="none" stroke="#000" stroke-width="3.37"/>
139 - </g>
140 - <g clip-path="url(#clippath-15)">
141 - <text transform="translate(629.03 147.7)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">Memory </tspan></text>
142 - <text transform="translate(730.23 147.7)" fill="#ccc" font-family="TrebuchetMS, &apos;Trebuchet MS&apos;" font-size="26.99"><tspan x="0" y="0">Access</tspan></text>
143 - </g>
144 -</svg>
\ No newline at end of file
docs/res/header.png
Binary files a/docs/res/header.png and b/docs/res/header.png differ
docs/res/joke.png
Binary files a/docs/res/joke.png and /dev/null differ
docs/res/memory-man.png
Binary files a/docs/res/memory-man.png and /dev/null differ
docs/res/new_vid.jpg
Binary files a/docs/res/new_vid.jpg and /dev/null differ
docs/res/physics-2.png
Binary files a/docs/res/physics-2.png and /dev/null differ
docs/res/physics.png
Binary files a/docs/res/physics.png and /dev/null differ
docs/res/profiles.png
Binary files /dev/null and b/docs/res/profiles.png differ
docs/res/prompts.png
Binary files a/docs/res/prompts.png and /dev/null differ
docs/res/quickstart/image-24.png
Binary files a/docs/res/quickstart/image-24.png and b/docs/res/quickstart/image-24.png differ
docs/res/quickstart/ui_chat_management.png
Binary files a/docs/res/quickstart/ui_chat_management.png and b/docs/res/quickstart/ui_chat_management.png differ
docs/res/quickstart/ui_newchat1.png
Binary files a/docs/res/quickstart/ui_newchat1.png and b/docs/res/quickstart/ui_newchat1.png differ
docs/res/settings-page-ui.png
Binary files a/docs/res/settings-page-ui.png and /dev/null differ
docs/res/settings-page-ui1.png
Binary files /dev/null and b/docs/res/settings-page-ui1.png differ
docs/res/setup/1-docker-image-search.png
Binary files a/docs/res/setup/1-docker-image-search.png and b/docs/res/setup/1-docker-image-search.png differ
docs/res/setup/2-docker-image-run-3.png
Binary files /dev/null and b/docs/res/setup/2-docker-image-run-3.png differ
docs/res/setup/2-docker-image-run.png
Binary files a/docs/res/setup/2-docker-image-run.png and b/docs/res/setup/2-docker-image-run.png differ
docs/res/setup/2-docker-image-run2.png
Binary files a/docs/res/setup/2-docker-image-run2.png and /dev/null differ
docs/res/setup/3-docker-port-mapping.png
Binary files a/docs/res/setup/3-docker-port-mapping.png and b/docs/res/setup/3-docker-port-mapping.png differ
docs/res/setup/4-docker-container-started.png
Binary files a/docs/res/setup/4-docker-container-started.png and b/docs/res/setup/4-docker-container-started.png differ
docs/res/setup/5-docker-click-to-open.png
Binary files a/docs/res/setup/5-docker-click-to-open.png and b/docs/res/setup/5-docker-click-to-open.png differ
docs/res/setup/6-docker-a0-running-new.png
Binary files a/docs/res/setup/6-docker-a0-running-new.png and b/docs/res/setup/6-docker-a0-running-new.png differ
docs/res/setup/9-rfc-devpage-on-docker-instance-1.png
Binary files a/docs/res/setup/9-rfc-devpage-on-docker-instance-1.png and b/docs/res/setup/9-rfc-devpage-on-docker-instance-1.png differ
docs/res/setup/9-rfc-devpage-on-local-sbs-1.png
Binary files a/docs/res/setup/9-rfc-devpage-on-local-sbs-1.png and b/docs/res/setup/9-rfc-devpage-on-local-sbs-1.png differ
docs/res/setup/a2a/a2a-conn.png
Binary files /dev/null and b/docs/res/setup/a2a/a2a-conn.png differ
docs/res/setup/a2a/a2a2.png
Binary files /dev/null and b/docs/res/setup/a2a/a2a2.png differ
docs/res/setup/docker-delete-image-1.png
Binary files a/docs/res/setup/docker-delete-image-1.png and b/docs/res/setup/docker-delete-image-1.png differ
docs/res/setup/image-1.png
Binary files a/docs/res/setup/image-1.png and b/docs/res/setup/image-1.png differ
docs/res/setup/image-10.png
Binary files a/docs/res/setup/image-10.png and b/docs/res/setup/image-10.png differ
docs/res/setup/image-11.png
Binary files a/docs/res/setup/image-11.png and b/docs/res/setup/image-11.png differ
docs/res/setup/image-12.png
Binary files a/docs/res/setup/image-12.png and b/docs/res/setup/image-12.png differ
docs/res/setup/image-13.png
Binary files a/docs/res/setup/image-13.png and b/docs/res/setup/image-13.png differ
docs/res/setup/image-14-u.png
Binary files a/docs/res/setup/image-14-u.png and b/docs/res/setup/image-14-u.png differ
docs/res/setup/image-14.png
Binary files a/docs/res/setup/image-14.png and b/docs/res/setup/image-14.png differ
docs/res/setup/image-15.png
Binary files a/docs/res/setup/image-15.png and b/docs/res/setup/image-15.png differ
docs/res/setup/image-16.png
Binary files a/docs/res/setup/image-16.png and b/docs/res/setup/image-16.png differ
docs/res/setup/image-17.png
Binary files a/docs/res/setup/image-17.png and b/docs/res/setup/image-17.png differ
docs/res/setup/image-18.png
Binary files a/docs/res/setup/image-18.png and b/docs/res/setup/image-18.png differ
docs/res/setup/image-19.png
Binary files a/docs/res/setup/image-19.png and b/docs/res/setup/image-19.png differ
docs/res/setup/image-2.png
Binary files a/docs/res/setup/image-2.png and b/docs/res/setup/image-2.png differ
docs/res/setup/image-20.png
Binary files a/docs/res/setup/image-20.png and b/docs/res/setup/image-20.png differ
docs/res/setup/image-21.png
Binary files a/docs/res/setup/image-21.png and b/docs/res/setup/image-21.png differ
docs/res/setup/image-22-1.png
Binary files a/docs/res/setup/image-22-1.png and b/docs/res/setup/image-22-1.png differ
docs/res/setup/image-23-1.png
Binary files a/docs/res/setup/image-23-1.png and b/docs/res/setup/image-23-1.png differ
docs/res/setup/image-3.png
Binary files a/docs/res/setup/image-3.png and b/docs/res/setup/image-3.png differ
docs/res/setup/image-4.png
Binary files a/docs/res/setup/image-4.png and b/docs/res/setup/image-4.png differ
docs/res/setup/image-5.png
Binary files a/docs/res/setup/image-5.png and b/docs/res/setup/image-5.png differ
docs/res/setup/image-6.png
Binary files a/docs/res/setup/image-6.png and b/docs/res/setup/image-6.png differ
docs/res/setup/image-7.png
Binary files a/docs/res/setup/image-7.png and b/docs/res/setup/image-7.png differ
docs/res/setup/image-8.png
Binary files a/docs/res/setup/image-8.png and b/docs/res/setup/image-8.png differ
docs/res/setup/image-9.png
Binary files a/docs/res/setup/image-9.png and b/docs/res/setup/image-9.png differ
docs/res/setup/image.png
Binary files a/docs/res/setup/image.png and b/docs/res/setup/image.png differ
docs/res/setup/macsocket.png
Binary files a/docs/res/setup/macsocket.png and b/docs/res/setup/macsocket.png differ
docs/res/setup/mcp/mcp-example-config.png
Binary files /dev/null and b/docs/res/setup/mcp/mcp-example-config.png differ
docs/res/setup/mcp/mcp-open-config.png
Binary files /dev/null and b/docs/res/setup/mcp/mcp-open-config.png differ
docs/res/setup/oses/apple.png
Binary files a/docs/res/setup/oses/apple.png and b/docs/res/setup/oses/apple.png differ
docs/res/setup/oses/linux.png
Binary files a/docs/res/setup/oses/linux.png and b/docs/res/setup/oses/linux.png differ
docs/res/setup/oses/windows.png
Binary files a/docs/res/setup/oses/windows.png and b/docs/res/setup/oses/windows.png differ
docs/res/setup/settings/1-agentConfig.png
Binary files a/docs/res/setup/settings/1-agentConfig.png and b/docs/res/setup/settings/1-agentConfig.png differ
docs/res/setup/settings/2-chat-model.png
Binary files a/docs/res/setup/settings/2-chat-model.png and b/docs/res/setup/settings/2-chat-model.png differ
docs/res/setup/settings/3-auth.png
Binary files a/docs/res/setup/settings/3-auth.png and b/docs/res/setup/settings/3-auth.png differ
docs/res/setup/settings/4-local-models.png
Binary files a/docs/res/setup/settings/4-local-models.png and b/docs/res/setup/settings/4-local-models.png differ
docs/res/setup/thumb_play.png
Binary files a/docs/res/setup/thumb_play.png and b/docs/res/setup/thumb_play.png differ
docs/res/setup/thumb_setup.png
Binary files a/docs/res/setup/thumb_setup.png and b/docs/res/setup/thumb_setup.png differ
docs/res/setup/update-initialize.png
Binary files a/docs/res/setup/update-initialize.png and b/docs/res/setup/update-initialize.png differ
docs/res/showcase-thumb.png
Binary files a/docs/res/showcase-thumb.png and b/docs/res/showcase-thumb.png differ
docs/res/splash_wide.png
Binary files a/docs/res/splash_wide.png and b/docs/res/splash_wide.png differ
docs/res/ui-actions.png
Binary files a/docs/res/ui-actions.png and /dev/null differ
docs/res/ui-attachments-2.png
Binary files a/docs/res/ui-attachments-2.png and /dev/null differ
docs/res/ui-attachments.png
Binary files a/docs/res/ui-attachments.png and /dev/null differ
docs/res/ui-behavior-change-chat.png
Binary files a/docs/res/ui-behavior-change-chat.png and /dev/null differ
docs/res/ui-context.png
Binary files a/docs/res/ui-context.png and /dev/null differ
docs/res/ui-file-browser.png
Binary files a/docs/res/ui-file-browser.png and /dev/null differ
docs/res/ui-history.png
Binary files a/docs/res/ui-history.png and /dev/null differ
docs/res/ui-katex-1.png
Binary files a/docs/res/ui-katex-1.png and /dev/null differ
docs/res/ui-katex-2.png
Binary files a/docs/res/ui-katex-2.png and /dev/null differ
docs/res/ui-nudge.png
Binary files a/docs/res/ui-nudge.png and /dev/null differ
docs/res/ui-restarting.png
Binary files a/docs/res/ui-restarting.png and /dev/null differ
docs/res/ui-screen-2.png
Binary files a/docs/res/ui-screen-2.png and /dev/null differ
docs/res/ui-screen.png
Binary files a/docs/res/ui-screen.png and /dev/null differ
docs/res/ui-settings-5-speech-to-text.png
Binary files a/docs/res/ui-settings-5-speech-to-text.png and /dev/null differ
docs/res/ui-tts-stop-speech.png
Binary files a/docs/res/ui-tts-stop-speech.png and /dev/null differ
docs/res/ui_screen.png
Binary files a/docs/res/ui_screen.png and /dev/null differ
docs/res/ui_screen2.png
Binary files /dev/null and b/docs/res/ui_screen2.png differ
docs/res/usage/action-btns.png
Binary files /dev/null and b/docs/res/usage/action-btns.png differ
docs/res/usage/api-int/api-int-1.png
Binary files /dev/null and b/docs/res/usage/api-int/api-int-1.png differ
docs/res/usage/api-int/api-int-2image-gen-api2.png
Binary files /dev/null and b/docs/res/usage/api-int/api-int-2image-gen-api2.png differ
docs/res/usage/api-int/api-int-3-api-key-missing-secrets.png
Binary files /dev/null and b/docs/res/usage/api-int/api-int-3-api-key-missing-secrets.png differ
docs/res/usage/api-int/api-int-4-secrets-setting.png
Binary files /dev/null and b/docs/res/usage/api-int/api-int-4-secrets-setting.png differ
docs/res/usage/api-int/api-int-5-finish.png
Binary files /dev/null and b/docs/res/usage/api-int/api-int-5-finish.png differ
docs/res/usage/attachments-1.png
Binary files /dev/null and b/docs/res/usage/attachments-1.png differ
docs/res/usage/attachments-2.png
Binary files /dev/null and b/docs/res/usage/attachments-2.png differ
docs/res/usage/file-browser.png
Binary files /dev/null and b/docs/res/usage/file-browser.png differ
docs/res/usage/file-edit.png
Binary files /dev/null and b/docs/res/usage/file-edit.png differ
docs/res/usage/first-task.png
Binary files /dev/null and b/docs/res/usage/first-task.png differ
docs/res/usage/memory-dashboard.png
Binary files /dev/null and b/docs/res/usage/memory-dashboard.png differ
docs/res/usage/memory-editing.png
Binary files /dev/null and b/docs/res/usage/memory-editing.png differ
docs/res/usage/multi-agent.png
Binary files /dev/null and b/docs/res/usage/multi-agent.png differ
docs/res/usage/nudge.png
Binary files /dev/null and b/docs/res/usage/nudge.png differ
docs/res/usage/projects/projects-activate-project.png
Binary files /dev/null and b/docs/res/usage/projects/projects-activate-project.png differ
docs/res/usage/projects/projects-creation.png
Binary files /dev/null and b/docs/res/usage/projects/projects-creation.png differ
docs/res/usage/projects/projects-desc-and-instructions.png
Binary files /dev/null and b/docs/res/usage/projects/projects-desc-and-instructions.png differ
docs/res/usage/projects/projects-first-ops.png
Binary files /dev/null and b/docs/res/usage/projects/projects-first-ops.png differ
docs/res/usage/projects/projects-git-projects-tree.png
Binary files /dev/null and b/docs/res/usage/projects/projects-git-projects-tree.png differ
docs/res/usage/projects/projects-gitprojects-clone.png
Binary files /dev/null and b/docs/res/usage/projects/projects-gitprojects-clone.png differ
docs/res/usage/restart.png
Binary files /dev/null and b/docs/res/usage/restart.png differ
docs/res/usage/tasks/edit-task.png
Binary files /dev/null and b/docs/res/usage/tasks/edit-task.png differ
docs/res/usage/tasks/scheduler-1.png
Binary files /dev/null and b/docs/res/usage/tasks/scheduler-1.png differ
docs/res/usage/ui-context1.png
Binary files /dev/null and b/docs/res/usage/ui-context1.png differ
docs/res/usage/ui-history1.png
Binary files /dev/null and b/docs/res/usage/ui-history1.png differ
docs/res/usage/ui-katex-2.png
Binary files /dev/null and b/docs/res/usage/ui-katex-2.png differ
docs/res/usage/ui-settings-5-speech-to-text.png
Binary files /dev/null and b/docs/res/usage/ui-settings-5-speech-to-text.png differ
docs/res/usage/ui-tts-stop-speech1.png
Binary files /dev/null and b/docs/res/usage/ui-tts-stop-speech1.png differ
docs/res/web-ui.mp4
Binary files a/docs/res/web-ui.mp4 and /dev/null differ
docs/res/web_screenshot.jpg
Binary files a/docs/res/web_screenshot.jpg and /dev/null differ
docs/res/win_webui2.gif
Binary files a/docs/res/win_webui2.gif and /dev/null differ
docs/setup/dev-setup.md renamed
+8 -8
@@ -138,22 +138,22 @@ My VS Code instance:
138 Agent Zero runs code inside the container by default. If you are running the framework locally in your IDE but want tools (like code execution) to run in Docker, configure RFC in **Settings -> Development** and point it to a running Agent Zero container. This routes execution through SSH/RFC to the container while keeping the UI and agent loop on your host.
139
140
141 -# 🎉 Congratulations! 🚀
141 +# Congratulations!
142
143 You have successfully set up a complete Agent Zero development environment! You now have:
144
145 -- ✅ A local development instance running in your IDE with full debugging capabilities
146 -- ✅ A dockerized instance for code execution and system operations
147 -- ✅ RFC and SSH communication between both instances
148 -- ✅ The ability to develop, debug, and test Agent Zero features seamlessly
145 +- A local development instance running in your IDE with full debugging capabilities
146 +- A dockerized instance for code execution and system operations
147 +- RFC and SSH communication between both instances
148 +- The ability to develop, debug, and test Agent Zero features seamlessly
149
150 -You're now ready to contribute to Agent Zero, create custom extensions, or modify the framework to suit your needs. Happy coding! 💻✨
150 +You're now ready to contribute to Agent Zero, create custom extensions, or modify the framework to suit your needs. Happy coding!
151
152
153 ## Next steps
154 -- See [extensibility](extensibility.md) for instructions on how to create custom extensions.
154 +- See [extensions](../developer/extensions.md) for instructions on how to create custom extensions.
155 - See [websocket infrastructure](websocket-infrastructure.md) for real-time handler patterns, client APIs, and troubleshooting tips.
156 -- See [contribution](contribution.md) for instructions on how to contribute to the framework.
156 +- See [contribution](../guides/contribution.md) for instructions on how to contribute to the framework.
157
158 ## Configuration via Environment Variables
159
docs/setup/installation.md renamed
+13 -7
@@ -38,6 +38,7 @@ Docker Desktop provides the runtime environment for Agent Zero, ensuring consist
38
39 ---
40
41 +<a name="windows-installation"></a>
42 ## <img src="../res/setup/oses/windows.png" width="30" alt="Windows"/> Windows Installation
43
44 **1.1. Download Docker Desktop**
@@ -67,6 +68,7 @@ Once installed, launch Docker Desktop from your Start menu or desktop shortcut.
68
69 ---
70
71 +<a name="macos-installation"></a>
72 ## <img src="../res/setup/oses/apple.png" width="30" alt="macOS"/> macOS Installation
73
74 **1.1. Download Docker Desktop**
@@ -103,6 +105,7 @@ Open Docker Desktop from your Applications folder.
105
106 ---
107
108 +<a name="linux-installation"></a>
109 ## <img src="../res/setup/oses/linux.png" width="30" alt="Linux"/> Linux Installation
110
111 **1.1. Choose Installation Method**
@@ -190,7 +193,7 @@ You can map just the `/a0/usr` directory (recommended) or individual subfolders
193 - Click the `Run` button
194
195 ![docker port mapping](../res/setup/2-docker-image-run.png)
193 -![docker port mapping](../res/setup/2-docker-image-run2.png)
196 +![docker volume mapping](../res/setup/2-docker-image-run-3.png)
197
198 The container will start and show in the "Containers" tab:
199
@@ -237,7 +240,7 @@ Agent Zero provides a comprehensive settings interface to customize various aspe
240 - **Knowledge Subdirectory:** Specify the location of custom knowledge files to enhance the agent's understanding.
241
242 > [!NOTE]
240 -> Since v0.9.8, custom prompts belong in `/a0/usr/agents/<agent_name>/prompts/` rather than a shared `/prompts` folder. See the [Extensibility guide](../development/extensibility.md#prompts) for details.
243 +> Since v0.9.7, custom prompts belong in `/a0/agents/<agent_name>/prompts/` rather than a shared `/prompts` folder. See the [Extensions guide](../developer/extensions.md#prompts) for details.
244
245 > [!NOTE]
246 > The Hacker profile is included in the main image. After launch, choose the **hacker** agent profile in Settings if you want the security-focused prompts and tooling. The "hacker" branch is deprecated.
@@ -311,7 +314,7 @@ Configure API keys for various service providers directly within the Web UI. Cli
314 - **RFC Parameters (local instances only):** Configure URLs and ports for remote function calls between instances
315 - **RFC Password:** Configure password for remote function calls
316
314 -Learn more about Remote Function Calls in the [Development guide](../development/setup.md#step-6-configure-ssh-and-rfc-connection).
317 +Learn more about Remote Function Calls in the [Development Setup guide](dev-setup.md#step-6-configure-ssh-and-rfc-connection).
318
319 > [!IMPORTANT]
320 > Always keep your API keys and passwords secure.
@@ -378,6 +381,7 @@ Ollama is a powerful tool that allows you to run various large language models l
381
382 ---
383
384 +<a name="windows-ollama-installation"></a>
385 ### <img src="../res/setup/oses/windows.png" width="30" alt="Windows"/> Windows Ollama Installation
386
387 Download and install Ollama from the official website:
@@ -388,6 +392,7 @@ Once installed, continue to [Pulling Models](#pulling-models).
392
393 ---
394
395 +<a name="macos-ollama-installation"></a>
396 ### <img src="../res/setup/oses/apple.png" width="30" alt="macOS"/> macOS Ollama Installation
397
398 **Using Homebrew:**
@@ -404,6 +409,7 @@ Once installed, continue to [Pulling Models](#pulling-models).
409
410 ---
411
412 +<a name="linux-ollama-installation"></a>
413 ### <img src="../res/setup/oses/linux.png" width="30" alt="Linux"/> Linux Ollama Installation
414
415 Run the installation script:
@@ -497,7 +503,7 @@ The Tunnel feature allows secure access to your Agent Zero instance from anywher
503 > [!IMPORTANT]
504 > **Security:** Always set a username and password in Settings → Authentication before creating a tunnel to secure your instance on the internet.
505
500 -For complete details on tunnel configuration and security considerations, see the [Tunneling guide](../advanced/tunneling.md).
506 +For complete details on tunnel configuration and security considerations, see the [Remote Access via Tunneling](../guides/usage.md#remote-access-via-tunneling) section in the Usage Guide.
507
508 ### Alternative: Local Network Access
509
@@ -510,7 +516,7 @@ If you prefer to keep access limited to your local network:
516 > [!TIP]
517 > Find your computer's IP address with `ipconfig` (Windows) or `ifconfig`/`ip addr` (macOS/Linux). It's usually in the format `192.168.x.x` or `10.0.x.x`.
518
513 -For developers or users who need to run Agent Zero directly on their system, see the [In-Depth Guide for Full Binaries Installation](../development/setup.md).
519 +For developers or users who need to run Agent Zero directly on their system, see the [In-Depth Guide for Full Binaries Installation](dev-setup.md).
520
521 ---
522
@@ -582,7 +588,7 @@ After following the instructions for your specific operating system, you should
588 **Next Steps:**
589
590 - For production server deployments, see the [VPS Deployment Guide](vps-deployment.md)
585 -- For development setup and extensions, see the [Development Guide](../development/setup.md)
586 -- For remote access via tunnel, see the [Tunneling Guide](../advanced/tunneling.md)
591 +- For development setup and extensions, see the [Development Setup Guide](dev-setup.md)
592 +- For remote access via tunnel, see [Remote Access via Tunneling](../guides/usage.md#remote-access-via-tunneling)
593
594 If you encounter any issues during the installation process, please consult the [Troubleshooting section](../guides/troubleshooting.md) of this documentation or refer to the Agent Zero [Skool](https://www.skool.com/agent-zero) or [Discord](https://discord.gg/B8KZKNsPpj) community for assistance.
docs/setup/vps-deployment.md renamed
+2 -2
@@ -173,7 +173,7 @@ A0_PORT="50080"
173 docker pull agent0ai/agent-zero:latest
174
175 # Run container
176 -docker run -d --name ${A0_NAME} --restart unless-stopped -p ${A0_PORT}:80 -v ${A0_PATH}/.env:/a0/.env -v ${A0_PATH}/work_dir:/a0/work_dir -v ${A0_PATH}/memory:/a0/memory -v ${A0_PATH}/logs:/a0/logs agent0ai/agent-zero:latest
176 +docker run -d --name ${A0_NAME} --restart unless-stopped -p ${A0_PORT}:80 -v ${A0_PATH}/.env:/a0/.env -v ${A0_PATH}/usr:/a0/usr agent0ai/agent-zero:latest
177 ```
178
179 ### Step 5: Verify Container
@@ -638,7 +638,7 @@ docker stop a0-instance
638 docker rm a0-instance
639
640 # Recreate with same settings
641 -docker run -d --name a0-instance --restart unless-stopped -p 50080:80 -v /opt/a0-instance/.env:/a0/.env -v /opt/a0-instance/work_dir:/a0/work_dir -v /opt/a0-instance/memory:/a0/memory -v /opt/a0-instance/logs:/a0/logs agent0ai/agent-zero:latest
641 +docker run -d --name a0-instance --restart unless-stopped -p 50080:80 -v /opt/a0-instance/.env:/a0/.env -v /opt/a0-instance/usr:/a0/usr -v /opt/agent-zero:latest
642 ```
643
644 ### Backup Strategy
docs/tutorials/README.md deleted
-20
@@ -1,20 +0,0 @@
1 -# Agent Zero Video Library
2 -
3 -Welcome to the visual guide for Agent Zero. Here you'll find tutorials, walkthroughs, and real-world use cases.
4 -
5 -## 📺 Basics
6 -- **[UI Walkthrough](basics.md)**: A tour of the interface, settings, and basic controls.
7 -- **[Installation Guide](https://www.youtube.com/watch?v=w5v5Kjx51hs)**: Getting started on your machine.
8 -
9 -## 💡 Use Case Showcases
10 -
11 -| Use Case | Description | Link |
12 -|----------|-------------|------|
13 -| **Data Analysis** | Financial trending, charting, and report generation | [View Guide](data-analysis.md) |
14 -| **Coding Assistant** | Building a full-stack web application from scratch | [View Guide](coding-assistant.md) |
15 -| **Deep Research** | Gathering papers, summarizing, and synthesizing info | [View Guide](research.md) |
16 -
17 -## 🎓 Advanced Tutorials
18 -- [MCP Server Setup](https://youtu.be/pM5f4Vz3_IQ)
19 -- [Projects & Workspaces](https://youtu.be/RrTDp_v9V1c)
20 -- [Memory Management](https://youtu.be/sizjAq2-d9s)
docs/tutorials/basics.md deleted
-9
@@ -1,9 +0,0 @@
1 -# UI Walkthrough
2 -
3 -*(Placeholder for screenshots of the new Dashboard, Chat Interface, and Settings)*
4 -
5 -## The Dashboard
6 -![Dashboard](/docs/res/splash_wide.png)
7 -
8 -## Chat Interface
9 -![Chat](/docs/res/ui-screen-2.png)
docs/tutorials/coding-assistant.md deleted
-5
@@ -1,5 +0,0 @@
1 -# Coding Assistant Use Case
2 -
3 -**Goal:** Build a React dashboard with real-time data visualization.
4 -
5 -*(Placeholder for step-by-step video/screenshots)*
docs/tutorials/data-analysis.md deleted
-5
@@ -1,5 +0,0 @@
1 -# Financial Analysis Use Case
2 -
3 -**Goal:** Analyze Bitcoin/USD price trends and generate a highlighted chart.
4 -
5 -*(Placeholder for step-by-step video/screenshots)*
docs/tutorials/research.md deleted
-5
@@ -1,5 +0,0 @@
1 -# Deep Research Use Case
2 -
3 -**Goal:** Gather and summarize recent AI papers about CoT prompting.
4 -
5 -*(Placeholder for step-by-step video/screenshots)*